C#中的多态特征与C++类似也存在相同的隐藏与运行时多态,但在C#中,隐藏特征需要通过关键字显示指明。在C#中,多态关键字有三个:
virtual: 如基类方法增加该关键字,则表明子类可重写此方法,重写分为两种:隐藏和多态。
new: 隐藏此方法,当进行类型赋值”slice”特征时,不进行多态调用,默认方式。
override: 重载(扩展)此方法,实现虚表多态性。
当处在继承链中,会根据定义的类、声明的类、多态关键字来决定调用的方法,下面类的继承结构如下:
new 关键字比较好理解,默认调用声明类所对应的方法,如下面的代码:
BaseClass bc = new BaseClass();
DerivedClass dc = new DerivedClass();
BaseClass bcdc = new DerivedClass();
DerivedClass sdc = new SubDerivedClass();
bc.Method1();//base-Method1
dc.Method1();//derived-Method1
bcdc.Method1();//base-Method1
因为BaseClass、DerivedClass类中的Method1方法均为new方式创建,隐藏基类方法,按照声明类型解析。
override关键字扩展基类方法,在调用此方法时,按照override关键字从基类开始进行搜索到继承链中最上面的方法(最后一个override定义的方法):
sdc.Method1();//SubDerivedClass-Method1
bc = sdc;
bc.Method1();//base-Method1
sdc从基类开始,发现SubDerivedClass为override方法,调用此方法,而bc从基类开始搜索,发现DerivedClass为new(隐藏)关键字,搜索截止,调用bc声明类型关键字。
我们如果修改方法定义如下:
调用代码如下:
bc.Method1();//base-Method1
dc.Method1();//derived-Method1
bcdc.Method1();//derived-Method1
sdc.Method1();//derived-Method1
bc = sdc;
bc.Method1();//derived-Method1
对象bc即使是SuperDerivedClass类型,由于override只到达DerivedClass级别,调用函数为DerivedClass对应的方法。
现在继续将类结构和方法修改定义如下:
测试代码如下:
SuperSubDerivedClass ssdc = new SuperSubDerivedClass();
bc = ssdc;
bc.Method1();//derived-Method1
sdc = ssdc;
sdc.Method1();//derived-Method1
这里对象bc、sdc均从基类开始进行搜索到最后一个override关键字对应的方法调用。