不同角度看C#多态

开发 后端
本文介绍了C#多态的三个问题,即一个简单的C#多态实现,如果继承中使用new而不是override关键字,多重继承。

封装、继承、多态,面向对象的三大特性,前两项理解相对容易,但要理解多态,特别是深入的了解,对于初学者而言可能就会有一定困难了。我一直认为学习OO的最好方法就是结合实践,封装、继承在实际工作中的应用随处可见,但C#多态呢?也许未必,可能不经意间用到也不会把它跟“多态”这个词对应起来。在此抛砖引玉,大家讨论,个人能力有限,不足之处还请指正。

之前看到过类似的问题:如果面试时主考官要求你用一句话来描述多态,尽可能的精炼,你会怎么回答?当然答案有很多,每个人的理解和表达不尽相同,但我比较趋向这样描述:通过继承实现的不同对象调用相同的方法,表现出不同的行为,称之为多态。

1、一个简单的C#多态实现(参考自http://www.cnblogs.com/glacierh/):

  1. public class Animal  
  2. {  
  3.     public virtual void Eat()  
  4.     {  
  5.         Console.WriteLine("Animal Eat ...");  
  6.     }  
  7. }  
  8.  
  9. public class Cat : Animal  
  10. {  
  11.     public override void Eat()  
  12.     {  
  13.         Console.WriteLine("Cat Eat ...");  
  14.     }  
  15. }  
  16.  
  17. public class Dog : Animal  
  18. {  
  19.     public override void Eat()  
  20.     {  
  21.         Console.WriteLine("Dog Eat ...");  
  22.     }  
  23. }  
  24.  
  25. class Program  
  26. {  
  27.     static void Main(string[] args)  
  28.     {  
  29.         Animal[] animals = new Animal[3];  
  30.  
  31.         animals[0] = new Animal();  
  32.         animals[1] = new Cat();  
  33.         animals[2] = new Dog();  
  34.  
  35.         for (int i = 0; i <  3; i++)  
  36.         {  
  37.             animals[i].Eat();  
  38.         }  
  39.     }  

输出结果:

Animal Eat ...

Cat Eat ...

Dog Eat ...

OK,从上面的例子可以看出,通过继承,使得Animal对象数组中的不同的对象,在调用Eat()方法时,表现出了不同的行为,这就是一个最简单的多态示例。

2、如果继承中使用new而不是override关键字

  1. public class Animal  
  2. {  
  3.     public virtual void Eat()  
  4.     {  
  5.         Console.WriteLine("Animal Eat ...");  
  6.     }  
  7. }  
  8.  
  9. public class Cat : Animal  
  10. {  
  11.     public override void Eat()  
  12.     {  
  13.         Console.WriteLine("Cat Eat ...");  
  14.     }  
  15. }  
  16.  
  17. public class Dog : Animal  
  18. {  
  19.     //注意此处用了 new 而不再是 override 关键字  
  20.     public new void Eat()  
  21.     {  
  22.         Console.WriteLine("Dog Eat ...");  
  23.     }  
  24. }  
  25.  
  26. class Program  
  27. {  
  28.     static void Main(string[] args)  
  29.     {  
  30.         Animal animal = new Animal();  
  31.         animal.Eat();  
  32.  
  33.         Animal cat = new Cat();  
  34.         cat.Eat();  
  35.  
  36.         Animal dog = new Dog();  
  37.         dog.Eat();  
  38.     }  

输出结果:

Animal Eat ...

Cat Eat ...

Animal Eat ...

从结果中可以看出,当派生类Dog的Eat()方法使用new修饰时,Dog的对象转换为Animal对象后,调用的是Animal类中的Eat()方法。其实可以理解为,使用new关键字后,使得Dog中的Eat()方法和Animal中的Eat()方法成为毫不相关的两个方法,只是它们的名字碰巧相同而已。也由此可以看出:多态,依赖override实现。

3、多重继承

如果class A有一个virtual method(),class B继承于class A,并override method(),class C又继承于class B,那么class C是否可以继续override method()并实现多态呢?看下面的例子:

  1. public class Animal  
  2. {  
  3.     public virtual void Eat()  
  4.     {  
  5.         Console.WriteLine("Animal Eat ");  
  6.     }  
  7. }  
  8.  
  9. public class Dog : Animal  
  10. {  
  11.     public override void Eat()  
  12.     {  
  13.         Console.WriteLine("Dog Eat ");  
  14.     }  
  15. }  
  16.  
  17. public class WolfDog : Dog  
  18. {  
  19.     public override void Eat()  
  20.     {  
  21.         Console.WriteLine("WolfDog Eat ");  
  22.     }  
  23. }  
  24.  
  25. class Program  
  26. {  
  27.     static void Main(string[] args)  
  28.     {  
  29.         Animal animal = new Animal();  
  30.         animal.Eat();  
  31.  
  32.         Animal dog = new Dog();  
  33.         dog.Eat();  
  34.  
  35.         Animal wolfdog = new WolfDog();  
  36.         wolfdog.Eat();  
  37.  
  38.     }  

输出结果:

Animal Eat ...

Dog Eat ...

WolfDog Eat ...

OK,现在得到了肯定的答案,不管继承关系包含了多少层,都可以在子类中对父类中已经重写的方法继续进行重写。即如果父类方法用override修饰,子类继承了该方法,同时也可以用override修饰,多重继承中的C#多态就是如此实现。要想终止这种重写,只需重写方法时使用sealed关键字。

【编辑推荐】

  1. 总结C#哈希表的用法
  2. 不一样的入门:看C# Hello World的17种写法
  3. 什么是WMI?及其示例
  4. 从C#到C++容易出现的问题解答
  5. 浅议.NET、ASP.NET和C#的关系
责任编辑:book05 来源: cnblogs
相关推荐

2009-08-27 16:03:31

从c#到c++

2018-04-20 08:37:23

灾难恢复数据备份

2010-01-03 20:52:27

2019-02-01 14:45:41

前端

2009-09-01 18:29:10

C#继承C#多态

2017-11-20 16:17:50

智慧城市

2009-09-01 14:51:19

C#多态性

2009-08-17 15:52:42

C#多态

2011-05-24 09:15:26

JavaC#

2018-06-26 10:59:31

虚拟化云计算核心技术

2009-08-28 16:48:50

C#多态性

2009-09-01 15:08:18

C#多态性

2009-08-25 09:58:56

C#参数不同点

2011-03-30 08:27:48

C#

2009-08-12 14:59:09

C#和Java不同点

2009-08-20 10:39:00

Java与C#的不同之

2020-02-04 09:53:05

数据安全数据泄漏信息安全

2019-04-28 16:10:50

设计Redux前端

2009-08-06 15:26:18

C#异常类型

2015-05-05 11:04:31

CoreOS自动化运维
点赞
收藏

51CTO技术栈公众号