多态
-
对象的多种形态
辛巴是狮子;
辛巴是动物。
Animal xinBa = new Lion();
-
行为的多种形态
同样的行为,但是表现形式不同。也就是说方法签名一样,方法体不同。(签名在这里指的是方法名、参数以及返回值)
行为的多态体现为方法的重写、隐藏、重载
方法隐藏
隐藏是实现多态的基本方法之一。
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 抽象方法:没有实现的方法
在实现类(子类 普通的类)中必须实现【重写】