运行时绑定仅体现在虚函数中因此在试验中输出的结果是CAFoo因为Foo没有被申明为virtual在编译阶段已经把caFoo绑定到CAFoo
Override只能用于虚函数中当子类继承基类他便拥有了基类所有的函数Override修饰的函数将替换基类原来的函数否则子类会新增加一个函数并同时保留基类中的函数 下面的这个例子很好的说明了这个问题
class CA{
public virtual void Foo(){
ConsoleWriteLine(CAFoo);
}
}
class CB : CA{
public override void Foo() {
ConsoleWriteLine(CBFoo);
}
}
class CC : CA {
public new void Foo() {
ConsoleWriteLine(CCFoo);
}
}
class Test {
public static void Main() {
ConsoleWriteLine(typeof(CB)GetMethods()Length); // 输出
ConsoleWriteLine(typeof(CC)GetMethods()Length);// 输出
}
}
这段程序输出CB和CC的函数个数CB的个函数中个来自于SysetmObject剩下的一个就是FooCC中多了一个函数因为使用了new (如果不使用new也是相同的结果因为C#编译器默认使用new但不显示指明new会给出一个警告)说明了CCFoo是一个不同于CAFoo的虚函数
所以在试验中不使用override我们在InvokeFoo中调用的还是CAFoo()虽然这个时候还是运行时绑定但是因为CBFoo并没有覆盖CAFoo因此我们还是得到了基类的实现
当一个函数不是虚函数的时候子类中相同签名的函数总是覆盖了父类中的函数并不需要override关键字所以c#编译器会把它当作一个错误如上表中试验所示
如果读者理解了上面的内容那么来看看一个略微复杂的情况我们邀请interface出场!
interface IA {
void Foo();
}
class CA: IA{
public void Foo(){
ConsoleWriteLine(CAFoo);
}
}
[问题]: Foo是虚函数吗?
答案是肯定的就像interface方法不能显示声明为public一样我们也不能在IAFoo前面加上virtual原因很简单所有的interface方法都是虚函数!在调用interface方法的时候总是要使用运行时绑定
[] [] []