.NET中的虚函数2011-01-12 MSDN博客 面向对象的程序设计有三大要素,封装、继承和多态。虚函数是多态的重要组成部分,同时又在类的继承关系中有着很多变化。本文讨论.NET中对虚函数的支持。首先,我们通过一个例子来看看虚函数的普通用法:
class CA {
public virtual void Foo() {
Console.WriteLine("CA.Foo");
}
}
class CB : CA {
public override void Foo() {
Console.WriteLine("CB.Foo");
}
}
class Test {
public static void InvokeFoo(CA ca) {
ca.Foo();
}
public static void Main() {
InvokeFoo(new CB());
}
}
输出结果CB.Foo在这个例子中,尽管在调用InvokeFoo()的时候,CB被转换成CA,但是当执行ca.Foo的时候,仍然调用了CB的Foo。因为ca此时指向的是一个CB类型的对象。这种调用模式,我们称之为运行时绑定。因为在编译InvokeFoo时,编译器无法获取参数ca的真实类型,只有在运行的时候,才能根据ca的真实类型,决定调用哪一个函数。在这个例子中,两个关键字值得我们注意,首先是virtual,他告诉编译器,当前函数需要运行时绑定。其次是override,他告诉编译器,我要覆盖基类中的Foo()。看到这里,可能读者会对两个问题持有疑惑:[问题]: 不用virtual结果如何?[问题]: 不用override结果如何?读者不妨自己动手修改上例,尝试这两个关键字的不同组合,看看输出的结果如何。在这里,我仅给出组合条件和其输出结果。
序号 | 基类(CA)中是否有virtual | 子类(CB)中是否有override | 输出 |
1 | 是 | 是 | CB.Foo |
2 | 是 | 否 | CA.Foo |
3 | 否 | 是 | 编译错误 |
4 | 否 | 否 | CA.Foo |