02-24 方法重写与虚方法调用

前一篇隐藏的实例中,由于子类隐藏了父类的同名方法,如果不进行强制转换,就无法通过父类变量直接调用子类的同名方法,哪怕父类变量引用的是子类变量。

我们希望的是每个对象“各司其职”。

为了达到这个目的,可以在父类同名方法前加关键字virtual,表明这是一个虚方法,子类可以重写此方法:即在子类同名方法前加关键字override,表明这是对父类同名方法进行了重写。

请看如下代码:

 1  class Parent   //父类
 2     {
 3         public virtual void OverrideF() //父类的虚方法方法
 4         {
 5             System.Console.WriteLine("Parent.OverrideF()");
 6         }
 7     }
 8     class Child : Parent  //子类继承父类
 9     {
10         public override void OverrideF()//子类的重写方法
11         {
12             System.Console.WriteLine("Child.OverrideF()");
13         }
14     }

请看一下使用代码(在主函数中调用):

1             Child c = new Child();
2             Parent p;
3             p = c;
4             p.OverrideF();//调用父类的还是子类的同名方法?

上述代码运行的结果:

这一事例表明,将父类方法定义为虚方法,子类重写同名方法之后,通过父类变量调用此方法,到底是调用父类还是子类的,由父类变量引用的真实对象类型决定,而与父类变量无关。

换句话说,同样一句代码:

  p.OverrideF();

在p引用不同对象时,其运行的结果完全不一样!因此,如果我们再编程时只针对父类变量提供的对外接口编程,就是我们的代码成了“变色龙”,传给它不同的子类对象(这些子类对象都重写了父类的同名方法),它就会做不同的事。这就是面向对象语言中的“虚方法调用”特性。这一特性会让我们写出非常灵活的代码,大大减少由于系统功能扩充和改变带来的大量代码修改工作量。

结论:

面向对象怨言拥有的“虚方法调用”特性,使我们可以只用同样的一个语句,在运行时根据对象类型而执行不同的操作。

 

posted @ 2015-02-24 20:38  小城菇凉  阅读(1242)  评论(0编辑  收藏  举报