多态是面向对象编程中三大机制之一,其原理建立在"从父类继承而来的子类可以转换为其父类"这个规则之上,换句话说,能用父类的地方,就能用该类的子类.当从父类派生了很多子类时,由于每个子类都有其不同的代码实现,所以当用父类来引用这些子类时,同样的操作而可以表现出不同的操作结果,这就是所谓的多态.

1.了解什么是多态性

2.如何定义一个虚方法

3.如何重载一个虚方法

4.如何在程序中运用多态性

面向对象程序设计中的另外一个重要概念是多态性。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。 可以把一组对象放到一个数组中,然后调用它们的方法,在这种场合下,多态性作用就体现出来了,这些对象不必是相同类型的对象。当然,如果它们都继承自某个类,你可以把这些派生类,都放到一个数组中。 如果这些对象都有同名方法,就可以调用每个对象的同名方法。本节课将向你介绍如何完成这些事情。

1.清单9-1. 带有虚方法的基类:DrawingObject.cs

using System;
public class DrawingObject
{
public virtual void Draw()
{
Console.WriteLine("I'm just a generic drawing object.");
}
}

说明

清单9-1
定义了DrawingObject类。这是个可以让其他对象继承的基类。该类有一个名为Draw()的方法。Draw()方法带有一个virtual修饰符,该修饰符表明:该基类的派生类可以重载该方法。DrawingObject类的
Draw()方法完成如下事情:输出语句"I'm just a generic drawing object."到控制台。

2.清单9-2. 带有重载方法的派生类:Line.cs, Circle.cs, and Square.cs

using System;
public class Line : DrawingObject
{
public override
void Draw()
{
Console.WriteLine("I'm a Line.");
}
}

public class Circle : DrawingObject
{
public override void Draw()

{
Console.WriteLine("I'm a Circle.");
}
}

public class Square : DrawingObject
{
public override void Draw()

{
Console.WriteLine("I'm a Square.");
}
}

说明

清单9-2定义了三个类。这三个类都派生自DrawingObject类。每个类都有一个同名Draw()方法,这些Draw()方法中的每一个都有一个重载修饰符。重载修饰符可让该方法在运行时重载其基类的虚方法,实现这个功能的条件是:通过基类类型的指针变量来引用该类。

3.清单9-3. 实现多态性的程序:DrawDemo.cs

using System;
public class DrawDemo
{
public static int
Main(string[] args)
{
DrawingObject[] dObj = new DrawingObject[4];

dObj[0] = new Line();
dObj[1] = new Circle();
dObj[2] = new
Square();
dObj[3] = new DrawingObject();
foreach (DrawingObject drawObj
in dObj)
{
drawObj.Draw();
}
return 0;
}
}

说明

清单9-3演示了多态性的实现,该程序使用了在清单 9-1 和清单9-2中定义的类。在DrawDemo类中的Main()方法中,创建了一个数组,
数组元素是DrawingObject 类的对象。该数组名为dObj,是由四个DrawingObject类型的对象组成。

接下来, 初始化dObj数组, 由于Line,
Circle和Square类都是DrawingObject类的派生类,所以这些类可以作为dObj数组元素的类型。
如果C#没有这种功能,你得为每个类创建一个数组。继承的性质可以让派生对象当作基类成员一样用,这样就节省了编程工作量。

一旦数组初始化之后,接着是执行foreach循环,寻找数组中的每个元素。在每次循环中, dObj
数组的每个元素(对象)调用其Draw()方法。多态性体现在:在运行时,各自调用每个对象的Draw()方法。尽管dObj
数组中的引用对象类型是DrawingObject,这并不影响派生类重载DrawingObject 类的虚方法Draw()。 在dObj
数组中,通过指向DrawingObject 基类的指针来调用派生类中的重载的Draw()方法。

输出结果是:

I'm a Line.
I'm a Circle.
I'm a Square.
I'm just a generic
drawing object.

在DrawDemo 程序中,调用了每个派生类的重载的Draw()方法。
最后一行中,执行的是DrawingObject类的虚方法Draw()。这是因为运行到最后,数组的第四个元素是DrawingObject类的对象。

小结
现在对多态性有所了解之后,你可以在派生类中,实现一个重载基类虚方法的方法。虚方法和重载的派生类方法之间的关系就体现出C#的多态性。

C#之多态的更多相关文章

  1. Java中的多态

    1.多态:具有表现多种形态的能力的特征 父类: public abstract class Animal {public abstract void Say();} 子类: public class ...

  2. C# 工厂模式+虚方法(接口、抽象方法)实现多态

    面向对象语言的三大特征之一就是多态,听起来多态比较抽象,简而言之就是同一行为针对不同对象得到不同的结果,同一对象,在不同的环境下得到不同的状态. 实例说明: 业务需求:实现一个打开文件的控制台程序的d ...

  3. C#非常重要基础之多态

    前几天看了一位同志的博客,写的是关于他自己去支付宝面试的经历.过程大体是这样的:问答的时候,前面部分,作者都应答如流,说起自己经验如何之丰富,最后面试官问了作者一个问题:请简述多态的概念和作用.结果这 ...

  4. C++多态详解

    多态是面向对象的程序设计的关键技术.多态:调用同一个函数名,可以根据需要但实现不同的功能.多态体现在两个方面,我们以前学过的编译时的多态性(函数重载)和现在我们这一章将要学习的运行时的多态性(虚函数) ...

  5. 【那些年关于java多态应用】

    1.多态:具有表现多种形态的能力的特征 父类: public abstract class Animal { public abstract void Say();} 子类: public class ...

  6. JAVA多态

    多态是指当系统A访问系统B的服务时,系统B可以通过多种方式来提供服务,而这一切对系统A是透明的.比如动物园的饲养员能够给各种各样的动物喂食.下图显示了饲养员Feeder,食物Food和动物Animal ...

  7. C#多态“说来也说”——逻辑层BLL中的多态使用

    本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址 http://www.cnblogs.com/tdws/p/5861842.html 昨天晚上,有个朋友说学了好久,依然没搞 ...

  8. java多态的理解

    面向对象语言中的类有三个特征,封装.继承.多态.封装与继承很好理解,那什么是多态呢? 1.什么是多态? 多态的定义:指允许不同类的对象对同一消息做出响应.即同一消息可以根据发送对象的不同而采用多种不同 ...

  9. java中如何实现多态

    复习基础知识 多态,就是重载和重写.重载发生在一个类中.重写发生在子类,意思就是子类重写父类相同名称的方法.刚学语言有的东西,不必搞得那么清楚,只有知道怎么用就行了,有的问题你要想真正把它搞得很懂,短 ...

  10. OC多态

    要点: 1.多种形态,引用的多种形态对于一个引用变量,可以指向任何类的对象.对于一个父类的引用(类与类之间有一种继承关系),可以指向子类,也可以指向本类,指向的类型不同.当通过此引用向对象发送消息,调 ...

随机推荐

  1. 项目中重新引用WCF报错

    今天在一个项目里,重新更新WCF引用的时候,居然报错了,提示根本找不到那个WCF接口,我赶紧跑去新建了一个空项目,试着用相同的地址引用一下,发现是可以的,完全ok 既然是虚惊一场,那就得想办法把这个W ...

  2. 【学习笔记】【C语言】循环结构-for

    1.使用: for (语句1; 条件; 语句2) {     循环体 }   语句1:初始化语句 语句2:增量语句(执行完循环体后再执行的语句)   1.for一开始就会执行一次语句1(整个for循环 ...

  3. 利用ExcelDataReader封装类 导入表格数据

    nuget 添加Install-Package ExcelDataReader

  4. org.springframework.util.Assert

    方法入参检测工具类 Web 应用在接受表单提交的数据后都需要对其进行合法性检查,如果表单数据不合法,请求将被驳回. 类似的,当我们在编写类的方法时,也常常需要对方法入参进行合 法性检查,如果入参不符合 ...

  5. unity基本操作二

    一:error1,先断网再启动点击Manual Activation点击Save License生成相应的alf文件2,联网打开https://license.unity3d.com/manual上传 ...

  6. Linux 内存布局

         本文主要简介在X86体系结构下和在ARM体系结构下,Linux内存布局的概况,力求简单明了,不过多深入概念,多以图示的方式来记忆理解,一图胜万言. Technorati 标签: 内存 布局 ...

  7. 新做的H5页面(具体应该说是百分比页面)

    主要代码 <div class="top" id="headTab"> <div id="photo"><a ...

  8. lighttpd的超时参数详解

    今天服务器上传大文件,服务器php一直没有响应,响应为0KB,经排查发现是lighttpd的超时设置问题 server.max-keep-alive-idle = 5server.max-read-i ...

  9. (一)在linux上ubuntu搭建hustOJ系统

    同实验室有人在用java写签到系统,正好我在学习PHP,我就在想能不能在以前学长留下来一直没用OJ上添加一个签到功能. 于是说干就干,就找了许多关于hustoj的文章参考. 首先要说的是安装husto ...

  10. dedecms 分页样式

    <div class="dede_pages">  <ul class="pagelist">   {dede:pagelist lis ...