4.9 多态
知识点讲解:光盘:视频\PPT讲解(知识点)\第4章\多态.mp4
多态性(polymorphism)也是面向对象程序设计的一个重要特征,它主要表现在函数调用时实现“一种接口、多种方法”。在C#中涉及的多态性大多是指运行时的多态性,即在调用具有相同继承关系的类的相同签名的函数成员时,直至程序运行完毕后才能确定调用哪个类的实例的构造函数成员。C#的运行多态性是通过在子类中重写基类的虚方法,或函数的成员来实现的。在具有继承关系的C#类中,不同对象的签名、相同函数的成员都可以有不同的实现方式,这样就会产生不同的执行结果,上述特性就称之为多态。在本节的内容中,将详细讲解多态的基本知识。
4.9.1 虚方法和虚方法重写
在C#中,使用关键字virtual来定义虚方法,反之没有virtual定义的方法则被称为非虚方法。虚方法的语法格式如下。
修饰符 virtual 方法()
{
}
关键字virtual不能和static、abstrct或override修饰符同时使用。因为虚拟成员不能是私有的,所以关键字virtual和private也不能同时使用。
如果在方法的声明中使用override修饰符,则称这个方法为重写方法。重写方法是用相同的签名来重写所继承的虚方法。其中虚方法的声明用于引入新方法,而重写方法的声明则使从基类继承来的虚方法专用化。
注意:关键字override不能和static、abstrct或virtual修饰符同时使用,并且重写方法只能用于重写基类的虚方法。
非虚方法的实现是不变的,无论是在声明该方法的类的实例中,还是在派生子类的实例中,当调用这个非虚方法时,它的实现都是相同的。也就是说,派生子类不能改变基类中声明的非虚方法。
4.9.2 重写方法的特点
通常将由override声名所重写的那个方法为已重写了的基方法。假如在C中声明了重写方法F(),已重写了的基方法是通过检查C的各个基类确定的,检查的方法是先从C的直接基类开始,逐一检查每个后续的直接基类,直到找到一个与nn具有相同签名的可访问方法。
只有包含override关键字的方法,才能重写另一个方法。否则,声明一个与从基类继承来的具有相同签名的方法,只会隐藏被继承的基类方法。例如下面的一段代码。
class mm
{
public virtual void chuli()
{
}
}
class nn:mm
{
public virtual void chuli() //警告
{
}
}
在上述代码中,nn中的方法chuli()没有包含override关键字,所以就不能重写mm中的方法chuli()。反之,nn中的方法chuli()隐藏了mm中的方法,并且因为在声明中没有使用new修饰符,所以会发生运行警告。
再看下面的一段代码。
class mm
{
public virtual void chuli()
{
}
}
class nn:mm
{
new private void chuli() //隐藏mm.chuli()
{
}
}
class zz:nn
{
public override void chuli() //重写mm.chuli()
{
}
}
在上述代码中,nn中的方法chuli()隐藏了从mm中继承的方法chuli()。因为nn中的方法chuli()有访问权限的问题,它的访问范围只包括nn类中,而在zz类中没有权限。所以,允许zz中的chuli()声明重写从mm类继承的方法chuli()。
在C#中的虚方法和非虚方法的调用原则如下。
- 当调用虚方法时,对象的运行类型决定了被调用的函数实现。
- 当调用非虚方法时,被调用函数取决于对该类派生程度最大的实现。