C#基础解析之 Ⅶ【多态】

今天继续和大家一起探讨C#,我们今天来聊聊C#中面向对象中一个重要的特性------多态

简单的一句话解释多态:相同的方法调用可以实现不同的实现方式

通俗的说多态就是不同的表现形式,比如:中国人吃饭用筷子,欧洲以及北美都用刀叉,还有一些另类的人种直接上手,虽然他们的行为方式不同,但是他们有一个目的就是吃饭!

说白了多态就是同一个操作(通常是指方法,也可以是属性,事件甚至是字段),根据不同的对象能实现不同的效果。

函数重载就是一个多态的表现。(面向过程的编程时是没有函数重载的)

多态性又分为两种,一种是编译时的多态性,一种是运行时的多态性。

编译时的多态性:编译时的多态性是通过重载来实现的。系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。

运行时的多态性:运行时的多态性是通过重写虚成员实现。系统运行时,才根据实际情况决定实现何种操作。

多态中有两个方法一个是重载一个是重写(这个两个方法在上一章继承中已经详细的提到了,在本章多态中就不做过多解释了),重载是方法名必须相同参数列表必须不相同返回值类型可以不相同;重写是相同的方法名称相同的参数列表相同的返回值类型。

我们首先来看一下抽象类,抽象类中有个关键字---abstract,凡是用abstract关键字修饰的类都是抽象类。例如:abstract class Animal{}

对于抽象类可能有些初学者不太明白为什么要使用抽象类,为什么不直接把父类中的方法实现,或者子类中实现一个和父类无关的新方法。对于抽象类我想用现实生活中的例子来说明一下。例如:两个人对话 “小陈,帮我把那个东西拿过来” 小陈:“你说的是把水杯拿过去吗?”

你要的是水杯类的对象,而东西是水杯的父类,通常东西类没有实例对象,但是我们有时需要东西的引用指向它的子类实例。在这个生活中的例子中,“东西”就是抽象类,水杯是它的子类,它不具体指某一类对象,却可以只带所有类型的对象,虽然它抽象,但是它很简单方便。

在我们编程过成中为了简单方便于是就用到了抽象类。

下面我们来一起使用一下抽象类

复制代码
 1 namespace abstracts
 2 {
 3     abstract class DriverMan    //抽象类,父类
 4     {
 5         public abstract void Driver();  //抽象方法
 6     }
 7 
 8     class CarDriver : DriverMan //子类,汽车驾驶员
 9     {
10         public override void Driver()   //重写抽象方法
11         {
12             Console.WriteLine("司机:布加迪威龙已经停在公司门口了");
13         }
14     }
15     class PlaneDriver : DriverMan //子类,飞行员
16     {
17         public override void Driver()
18         {
19             Console.WriteLine("飞行员:亚特兰蒂斯号准备升空");
20         }
21     }
22 }
复制代码

然后再在Main方法中实例两个子类对象,调用Driver方法。

复制代码
 1         static void Main(string[] args)
 2         {
 3             Console.WriteLine("李晓峰准备去参加WCG世界总决赛,请把汽车准备好");
 4             DriverMan dm = new CarDriver();//用父类实例化司机对象
 5             dm.Driver();//调用驾驶方法
 6             Console.WriteLine("通知机场,李晓峰的飞机马上要起飞了");
 7             DriverMan dm1 = new PlaneDriver();//用父类实例化飞行员对象
 8             dm1.Driver();//调用驾驶方法
 9             Console.ReadKey();
10         }
复制代码

运行结果:

创建抽象类的语法:

访问修饰符 abstract class 类名

在抽象类中定义抽象类方法的语法:

访问修饰符 abstract 返回类型 方法名(参数列表);

子类继承抽象类后,必须重写抽象类的抽象方法:

访问修饰符 override 返回类型 方法名(参数列表)
{
  方法体
}

需要注意一下的是,在子类重写父类的抽象方法时,访问修饰符、返回类型、方法名和参数列表必须和父类的抽象方法一致。

 

接下来我们来简单的了解一下虚方法。

首先我们为什么要用虚方法呢?在上面的抽象类中我们了解到我们都是采用的父类的抽象方法在子类中重写,因为抽象方法时没有方法体的,所以当遇到某些需要父类的方法有方法体时我们就用到了虚方法。

比如说:警察是保护公民的生命及财产安全的,具有擒拿格斗的功夫,而交警就不会这些,他们只会指挥交通,所以交警继承警察的同时必须重写父类的行为方法,而父类警察也要实现自己的行为方法。在这种情况下我们就需要学习虚方法了。

我们来用个控制台明确一下我们的思路:

复制代码
 1   class Policeman    //父类
 2     {
 3         public virtual void Responsibility()  //虚方法,有方法体
 4         {
 5             Console.WriteLine("警察,职责是保卫人民的生命财产安全");
 6         }
 7     }
 8 
 9     class TrafficPolice : Policeman //子类
10     {
11         public override void Responsibility()   //重写父类的虚方法
12         {
13             Console.WriteLine("交警,职责是指挥交通");
14         }
15     }
复制代码

在Main方法中实例化父类和子类对象并调用各自的Responsibity方法。

复制代码
1 static void Main(string[] args)
2         {
3             Policeman man = new Policeman();  //实例化父类对象
4             man.Responsibility();   //调用父类的方法
5             TrafficPolice tman = new TrafficPolice();   //实例化子类对象
6             tman.Responsibility();  //调用子类的方法
7             Console.ReadKey();
8         }
复制代码

运行结果:

父类中定义虚方法的语法:

访问修饰符 virtual 返回类型 方法名(参数列表)
{
  方法体
}

在这里说明一下:虚方法相比抽象方法,它更像一个普通方法,加关键字virtual的目的就是为了方便子类重写。因为普通方法用override在子类中重写会报错,在C#里面是不可以滴。还有就是具有虚方法的类不一定是抽象类,但是具有抽象方法的类一定是抽象类。需要注意的是虚方法在子类中可以不重写。如果虚方法没有被子类重写,再类对象调用的就是父类的虚方法。而抽象方法就必须在子类中重写。

总结:1.什么是多态,对于多态的解释。

   2.抽象类

     3.虚方法

 OK !今天就和大家讨论到这吧!  今天的内容不多!不过还是本着一个原则,那就是细腻、容易理解。我个人感觉这些内容对新手的帮助还是很大的。还是那句话只要我所写的东西对大家有用或者有一点点帮助,那么我的分享就有价值。。。

posted @ 2012-07-11 10:09  sunny's blog  阅读(260)  评论(0编辑  收藏  举报