C#多态

来源:互联网 发布:淘宝卖家联系方式修改 编辑:程序博客网 时间:2024/04/30 01:17

首先理解一下什么叫多态。同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性

多态性通过派生类覆写基类中的虚函数型方法或者抽象方法来实现。

多态性分为两种,一种是编译时的多态性,一种是运行时的多态性

编译时的多态性:编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。

运行时的多态性:运行时的多态性就是指直到系统运行时,才根据实际情况决定实现何种操作。C#中运行时的多态性是通过覆写虚成员实现。

 下面我们来分别说明一下多态中涉及到的四个概念:重载,覆写,虚方法和抽象方法。

重载和覆写的区别:

重载

类中定义的方法的不同版本

         public int Calculate(int x, int y)

         public double Calculate(double x, double y)

特点(两必须一可以)

         方法名必须相同

         参数列表必须不相同

         返回值类型可以不相同

覆写

         子类中为满足自己的需要来重复定义某个方法的不同实现。

         通过使用override关键字来实现覆写。

         只有虚方法和抽象方法才能被覆写。

         要求(三相同)

                   相同的方法名称

                   相同的参数列表

                   相同的返回值类型

最后再来介绍一下虚方法和抽象方法

虚方法:

声明使用virtual关键字。

调用虚方法,运行时将确定调用对象是什么类的实例,并调用适当的覆写的方法。

虚方法可以有实现体。

抽象方法:

必须被派生类覆写的方法。

可以看成是没有实现体的虚方法。

如果类中包含抽象方法,那么类就必须定义为抽象类,不论是否还包含其他一般方法。


注意:

昨天突然发现c#,和c++俩种语言在多态性的实现机制上面的细微差别。
   
如果是C++,在基类的构造函数里面调用虚函数的话,会调用本类的不会调用派生类的,原因是基类构造的时候,虚表还没有被派生类继承和修改。

    但如果是C#,那就不同了,在基类的构造函数里面照样调用派生类的。不知道有谁知道c#它的这种底层机制是怎样的?
-------是这样的,C++会先初始化基类,然后逐级初始化派生类型。C#则是一开始就把对象创建好了,然后逐个调用构造函数。本质区别在于C++的构造函数的任务是初始化,C#则不然,C#的类型的任何字段不必初始化,均有默认值,所以C#在调用构造函数之前就已经将对象初始化完毕了,所以会调用子类覆写的函数

通过继承,一个类可以用作多种类型:可以用作它自己的类型、任何基类型,或者在实现接口时用作任何接口类型。这称为多态性。C#中的每种类型都是多态的。类型可用作它们自己的类型或用作Object实例,因为任何类型都自动将Object当作基类型。  
   
  多态性不仅对派生类很重要,对基类也很重要。任何情况下,使用基类实际上都可能是在使用已强制转换为基类类型的派生类对象。基类的设计者可以预测到其基类中可能会在派生类中发生更改的方面。例如,表示汽车的基类可能包含这样的行为:当考虑的汽车为小型货车或敞篷汽车时,这些行为将会改变。基类可以将这些类成员标记为虚拟的,从而允许表示敞篷汽车和小型货车的派生类重写该行为。

 总结

虚方法:

1 virtual override对应。

2 子类经常调用基类的虚方法,base.(基类的虚方法)

 抽象类:

 1 abstract override对应。

2 抽象方法只能有小括号(),没有花括号{},也就是不能实现方法主体

3 抽象属性的get set后直接加分号,不能实现属性主体

4 抽象类的子类如果不是抽象类,则子类必须实现抽象类的所有方法和属性。

5 抽象类不能实例化,但在抽象类中定义一个受保护(protected)的构造函数,则在创建派生类的实例时,基类可执行初始化任务。

比较虚方法和抽象类

1 虚方法有一个实现部分,并为派生类提供了覆盖该方法的选项。抽象方法没有实现部分,强制派生类覆盖该方法。

2 abstract 方法必须在派生类中重写,而virtual则不必!

3 abstract 方法不能实现方法实体,而virtual则可以!

 

在实现多态时

虚方法:如果所有子类都要实现一些共同的功能的时候,我们倾向于虚方法,把功能变成虚方法,用Base关键字调用。、

抽象类:如果所有子类的方法都不同的时候,我们用抽象类

  

虚方法练习

using System;

using System.Collections.Generic;

using System.Text;

class employee

{

    protected string _name;

    public employee() { }

    public employee(string name)

    {

        _name = name;

    }

    public virtual void StartWork()

    {

        Console.Write(_name + "开始工作:");

    }

}

 class Manager:employee

{

    public Manager(string name):base(name){}

    public override void  StartWork()

{

     base.StartWork();

      Console.Write("给员工下达任务");

}

}

 class Secretary:employee

{

    public Secretary(string name):base(name){}

    public override void  StartWork()

{

     base.StartWork();

      Console.Write("配合经理工作");

}

}

 

class Seller:employee

{

    public Seller(string name):base(name){}

    public override void  StartWork()

{

       base.StartWork();

      Console.Write("销售产品");

}

}

 

class Account:employee

{

    public Account(string name):base(name){}

    public override void  StartWork()

{

        base.StartWork();

        Console.Write("管理财务");

}

}

 

class test

{

     static void Main()

    {

        employee [] emp=new employee[4];

        emp[0]=new Manager("张三");

        emp[1]=new Secretary("李四");

        emp[2]=new Seller("王五");

        emp[3]=new Account("马六");

        Console.WriteLine("早上8点,开始工作");

        foreach(employee e in emp )

        {

            e.StartWork();

        }

    }

}

   

 

抽象类的练习

  abstract class employee

{

    protected string _name;

  protected  employee(string name)

    {

        _name = name;

    }

       public abstract void StartWork();

   

}

 

class Manager:employee

{

    public Manager(string name):base(name){}

    public override void  StartWork()

{

 

      Console.Write(_name+"给员工下达任务");

}

}

 

class Secretary:employee

{

    public Secretary(string name):base(name){}

    public override void  StartWork()

{

 

      Console.Write(_name+"配合经理工作");

}

}

 

class Seller:employee

{

    public Seller(string name):base(name){}

    public override void  StartWork()

{

      Console.Write(_name+"销售产品");

}

}

 

class Account:employee

{

    public Account(string name):base(name){}

    public override void  StartWork()

{

      Console.Write(_name+"管理财务");

}

}

 

class test

{

     static void Main()

    {

        employee [] emp=new employee[4];

        emp[0]=new Manager("张三");

        emp[1]=new Secretary("李四");

        emp[2]=new Seller("王五");

        emp[3]=new Account("马六");

        Console.WriteLine("早上8点,开始工作");

        foreach(employee e in emp )

        {

            e.StartWork();

        }

    }

原创粉丝点击