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