继承(下)

4.4方法重载、隐藏与虚方法调用

      由于子类对象同时汇集了父类和子类的所有公共方法,而 C#并未对子类和父类的

方法名称进行过多限制,因此,一个问题出现了:

      如果子类中某个方法与父类方法的签名一样(即方法名和方法参数都一样),那当通过

子类对象访问此方法时,访问的是子类还是父类所定义的方法?

      让我们先从子类方法与父类方法之间的关系说起。

      总的来说,子类方法与父类方法之间的关系可以概括为以下三种。

  • 扩充(Extend):子类方法,父类没有;
  • 重载(Overload):子类有父类的同名函数,但参数类型或数目不一样;
  • 完全相同:子类方法与父类方法从方法名称到参数类型完全一样。

      对于第一种扩充关系,由于子类与父类方法不同名,所以不存在同名方法调用的问

题,重点分析一下后两种情况.

(1)重载(overload)

      在前面介绍过方法重载的概念,在同一个类中构成重载的方法主要根据参数列表来决定

调用哪一个。这一基本判断方法可以推广到类的继承情况。

      例如,以下代码在子类和父类中定义了一个重载的方法 OverloadF():

 

(2)隐藏(Hide)

      当子类与父类拥有完全一样的方法时,称子类隐藏了父类的同名方法,请看示例项目 HideExamples:

 

 

     请注意现在子类和父类都拥有了一个完全相同的方法 HideF(),于是问题发生了,请看

以下代码:

      Child c = new  Child();

      c.HideF();//调用父类的还是子类的同名方法?

Child c = new  Child();

Parent  p;

p = c;

p.HideF(); //调用父类的还是子类的同名方法?

 

     上述代码的运行结果是:

 

      Parent.HideF()

 

      这就意味着即使 Parent变量  p中实际引用的是  Child类型的对象,通过  p调用的方法还

 

是 Parent类的!

 

      如果确实希望调用的子类的方法,应这样使用:

 

      ((Child)p).HideF();

 

      即先进行强制类型转换。

 

      回到前面 Parent和  Child类的定义,Visual  Studio在编译这两个类时,会发出一个警告:

 

      警告1“HideExamples.Child.HideF()”隐藏了继承的成员

 

      “HideExamples.Parent.HideF()”。如果是有意隐藏,请使用关键字 new。

 

      虽然上述警告并不影响程序运行结果,却告诉我们代码不符合     C#的语法规范,修改

 

Child类的定义如下:

 

      class Child :  Parent

 

     {

 

           public new void HideF()

 

        {

 

             System.Console.WriteLine("Child.HideF()");

 

         }

 

     }

 

      “new”关键字明确告诉 C#编译器,子类隐藏父类的同名方法,提供自己的新版本。

 

      由于子类隐藏了父类的同名方法,所以如果要在子类方法的实现代码中调用父类被隐藏

 

的同名方法,请使用 base关键字,示例代码如下:

 

base.HideF(); //调用父类被隐藏的方法

 

(3)重写(override)与虚方法调用

 

      上述隐藏的示例中,由于子类隐藏了父类的同名方法,如果不进行强制转换,就无法通

 

过父类变量直接调用子类的同名方法,哪怕父类变量引用的是子类对象。

 

      这是不太合理的。我们希望每个对象都只干自己职责之内的事,即如果父类变量引用

 

的是子类对象,则调用的就是子类定义的方法,而如果父类变量引用的就是父类对象,则调

 

用的是父类定义的方法。这就是说,希望每个对象都各人自扫门前雪,莫管他人瓦上霜

 

      为达到这个目的,可以在父类同名方法前加关键字 virtual,表明这是一个虚方法,子类

 

可以重写此方法:即在子类同名方法前加关键字 override,表明对父类同名方法进行了重写。

 

      请看示例代码(示例项目 VirtualExamples):

      class  Parent

    {

          public  virtual void OverrideF()

        {

               System.Console.WriteLine("Parent.OverrideF()");

         }

     }

      class Child :  Parent

    {

            public  override void OverrideF()

       {

               System.Console.WriteLine("Child.OverrideF()");

        }

     }

      请看以下使用代码:

posted on 2015-02-26 10:54  星空丶那一抹流光  阅读(167)  评论(0编辑  收藏  举报

导航