天天看点

C#面向对象(三)多态

多态

  1. 对象的多种形态

    辛巴是狮子;

    辛巴是动物。

    Animal xinBa = new Lion();

  2. 行为的多种形态

    同样的行为,但是表现形式不同。也就是说方法签名一样,方法体不同。(签名在这里指的是方法名、参数以及返回值)

    行为的多态体现为方法的重写、隐藏、重载

方法隐藏

隐藏是实现多态的基本方法之一。

class Program
    {
        static void Main(string[] args)
        {
           Animal animal2 = new Animal();
            animal2.print();
            Lion xinBa = new Lion();
            xinBa.print();
            Animal animal = new Lion();
            animal.print();
            Console.ReadKey();
        }
    }
    class Animal
    {
        public void print()
        {
            Console.WriteLine("animal");
        }
    }
    class Lion:Animal
    {
        new public void print()
        {
            Console.WriteLine("lion");
        }
    }           
该程序输出:
animal
lion
animal
           

方法隐藏不能够实现父类调用子类

方法重写

方法重写解决父类所定义方法在子类中不适用(虚方法),

或父类没有实现(抽象方法),这样的方法子类可以重写,

重写是为了满足子类对该方法的不同需求.

1. 虚方法重写

virtual 方法在子类可以重写,父类方法的做法与子类不同
           

2. 抽象方法重写=抽象方法的实现

abstract 方法在子类必须重写,除非子类也是抽象类
           

3. 重写方法的重写 (重写方法被标识为sealed不能再被重写了)

已经重写过的方法,在子类还可以继续重写,除非被标识为sealed
           

虚方法

定义: 用vritual关键修饰的已经实现的方法,即是虚方法 。

特点: 虚方法表示一个可以在子类中重写的方法。

class Program
    {
        static void Main(string[] args)
        {
           Animal animal2 = new Animal();
            animal2.print();
            Lion xinBa = new Lion();
            xinBa.print();
            Animal animal = new Lion();
            animal.print();
            Console.ReadKey();
        }
    }
    class Animal
    {
        virtual public void print()
        {
            Console.WriteLine("animal");
        }
    }
    class Lion:Animal
    {
        override public void print()
        {
            Console.WriteLine("lion");
        }
    }           
输出结果
animal
lion
lion
           

虚方法可以实现父类调用子类

比较隐藏和重写
共性:都是多态实现的基本方式
不同:
1. 实际应用中 隐藏很少用【可以实现选择性的复用,不能父调子】 重写用的多【可以实现选择性的复用,能父调子】需求多
2. 实现原理不同,隐藏的性能高于重写。
3. 隐藏是静态绑定,性能高,快,不灵活;重写是动态绑定,性能低,慢,灵活。
           
方法隐藏的原理
方法隐藏是子类的方法表加入一个新项,
新项中表示的方法签名与继承来的方法签名一致,
但是在方法表中不能出现相同签名的方法项,
所以必须要隐藏掉一个。
子类用新项隐藏旧项。方法隐藏是在方法表加新项
           
方法重写的原理
父类的方法在子类重写后,
是子类型将方法表中相应方法签名对应的方法所在的地址重写了,
重写后,原方法签名项关联到新方法的地址。
当引用调用该方法时,访问新地址中的方法。
所以方法重写后,不管是通过父类还是子类型的引用,
调用方法时,都调用对象真实类型中定义的方法
如:A是父类,B是子类,A中Show方法在子类中重写
A obj = new B(); //A类型引用指向B类型的对象
obj.Show();
此时调用的是B类型定义的Show方法.
           

抽象类

定义:抽象类表示一个抽象概念,

在C#语法,指的就是用abstract修饰的类即为抽象类

特点:

1. 可以被继承,不能实例化(抽象类不能创建对象 new 抽象类自己)。

2. 抽象类中可能包含抽象成员(方法,属性),可以有也可以没有(空)。

抽象方法

定义:只要声明没有实现的方法,就是抽象方法。

特点:抽象方法必须放在抽象类或者接口中。

抽象类中的抽象方法必须使用abstract修饰符

比较抽象类中的抽象方法和虚方法

1   虚方法:virtua1修饰的已经实现的方法
    可以重写也可以不重写
2   抽象方法:没有实现的方法
    在实现类(子类 普通的类)中必须实现【重写】