02-24 面向对象--方法重载、隐藏

在面向对象思想中,由于基本特性--继承所致,产生了子类继承父类的关系,所以出现重载方法。

由于子类对象同事“汇聚了”父类和子类的方法所有公共方法,而C#并未对子类和父类的方法名称过多的 加以限制,因此会出现一些问题。

如果子类中的某个方法与父类方法的签名一致(即方法名和方法参数一样),那当通过子类对象访问此方法时,访问的是子类方法还是父类方法?

这就需要先从子类方法和父类方法之间的关系说起,总的来说,子类方法和父类方法之间的关系可以概括为一下三种。

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

对于第一种"扩充"关系,由于子类与父类方法不同名,所以不存在同名方法调用的问题,重点分析后两种情况。

(1)重载

在上面已介绍过方法重载的概念,再同一个类中构成重载的方法主要根据参数列表来决定调用哪一个。这一基本判断方法可以推广到类的继承情况。

 

 1 namespace _20141212jicheng
 2 {
 3     class Parent   //父类
 4     {
 5         public void OverloadF() //父类的方法
 6         {
 7         }
 8     }
 9     class Child : Parent  //子类继承父类
10     {
11         public void OverloadF(int i)//子类的方法(带参数的方法)
12         {         
13         }
14     }
15 }

 

使用代码如下:

1   static void Main(string[] args)
2         {
3 
4             Child obj = new Child();
5             obj.OverloadF(); //调用父类的重载方法
6             obj.OverloadF(100);  //调用子类的重载方法
7 
8         }

可看出,虽然重载的方法分布在不同的类中,但仍然可以将其看成是定义在同一类中的,其使用方法与调用类的其他方法并无不同。

(2)隐藏

当子类与父类拥有完全一样的方法时,称“子类隐藏了父类的同名方法”,请看实例项目。

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

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

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

上述代码运行时,输出:

修改以下代码:

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

上述代码运行结果:

由此得出结论:

当分别位于父类和子类的两个方法完全相同时,调用哪个方法由对象变量的类型决定。

然而,面向对象的继承特性允许使用子类对象被当成父类对象使用,这就问题复杂化了,以下代码运行时,会出现什么结果?

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

上述代码运行结果:

这就意味着即使Parent变量P中世纪引用的是Child类型的对象,通过P调用的方法还是Parent类的;

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

1   ((Child) p).HideF();

运行结果:

即先进行强制类型转换。

回到前面的Parent和Child类的定义,VS在编译这两个类时,会发出一个不符合C#语句规范的警告,修改之后:

1  class Child : Parent  //子类继承父类
2     {
3         public new  void HideF()//子类的方法
4         {
5             System.Console.WriteLine("Child.HideF()");
6         }
7     }

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

由于子类隐藏了父类的同名方法,所以如果要在子类方法的实现代码中调用父类被隐藏的同名方法,请使用base关键字,代码如下:

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

 

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