深入剖析C#多态性

摘要:
本课将介绍C#多态性。它的目的包括:1.了解多态性是什么。2.如何定义虚拟方法。3.如何重载虚拟方法。4.如何在程序中使用多态性。面向对象编程中的另一个重要概念是多态性。在运行时,可以通过指向基类来调用派生类中的方法。您可以将一组对象放入数组并调用它们的方法。在这种情况下,多态性得到了反映。这些对象不需要是相同类型的对象。当然,如果它们都继承自某个类,您可以

 

 

本节课将介绍C#的多态性,其目的包括:
1.了解什么是多态性

2.如何定义一个虚方法

3.如何重载一个虚方法

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

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

深入剖析C#多态性第1张using System;
深入剖析C#多态性第1张
public class DrawingObject
深入剖析C#多态性第3张深入剖析C#多态性第4张
深入剖析C#多态性第5张{
深入剖析C#多态性第6张
public virtual void Draw()
深入剖析C#多态性第7张深入剖析C#多态性第8张
深入剖析C#多态性第5张{
深入剖析C#多态性第6张Console.WriteLine(
"I'm just a generic drawing object.");
深入剖析C#多态性第11张}

深入剖析C#多态性第12张}


说明

清单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

深入剖析C#多态性第13张using System;
深入剖析C#多态性第13张
public class Line : DrawingObject
深入剖析C#多态性第15张深入剖析C#多态性第16张
深入剖析C#多态性第17张{
深入剖析C#多态性第18张
public override void Draw()
深入剖析C#多态性第19张深入剖析C#多态性第20张
深入剖析C#多态性第17张{
深入剖析C#多态性第18张Console.WriteLine(
"I'm a Line.");
深入剖析C#多态性第23张}

深入剖析C#多态性第24张}

深入剖析C#多态性第13张
深入剖析C#多态性第13张
public class Circle : DrawingObject
深入剖析C#多态性第15张深入剖析C#多态性第16张
深入剖析C#多态性第17张{
深入剖析C#多态性第18张
public override void Draw()
深入剖析C#多态性第19张深入剖析C#多态性第20张
深入剖析C#多态性第17张{
深入剖析C#多态性第18张Console.WriteLine(
"I'm a Circle.");
深入剖析C#多态性第23张}

深入剖析C#多态性第24张}

深入剖析C#多态性第13张
深入剖析C#多态性第13张
public class Square : DrawingObject
深入剖析C#多态性第15张深入剖析C#多态性第16张
深入剖析C#多态性第17张{
深入剖析C#多态性第18张
public override void Draw()
深入剖析C#多态性第19张深入剖析C#多态性第20张
深入剖析C#多态性第17张{
深入剖析C#多态性第18张Console.WriteLine(
"I'm a Square.");
深入剖析C#多态性第23张}

深入剖析C#多态性第24张}

深入剖析C#多态性第13张


说明

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

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

深入剖析C#多态性第1张using System;
深入剖析C#多态性第1张
public class DrawDemo
深入剖析C#多态性第3张深入剖析C#多态性第4张
深入剖析C#多态性第5张{
深入剖析C#多态性第6张
public static int Main(string[] args)
深入剖析C#多态性第7张深入剖析C#多态性第8张
深入剖析C#多态性第5张{
深入剖析C#多态性第6张DrawingObject[] dObj 
= new DrawingObject[4];
深入剖析C#多态性第6张dObj[
0= new Line();
深入剖析C#多态性第6张dObj[
1= new Circle();
深入剖析C#多态性第6张dObj[
2= new Square();
深入剖析C#多态性第6张dObj[
3= new DrawingObject();
深入剖析C#多态性第6张
foreach (DrawingObject drawObj in dObj)
深入剖析C#多态性第7张深入剖析C#多态性第8张
深入剖析C#多态性第5张{
深入剖析C#多态性第6张drawObj.Draw();
深入剖析C#多态性第11张}

深入剖析C#多态性第6张
return 0;
深入剖析C#多态性第11张}

深入剖析C#多态性第12张}


说明

清单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#多态性》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[转]ORA00257解决如何在CentOS 6.4上安装并使用OpenVZ?下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

聚合类型与POD类型

Lippman在《深度探索C++对象模型》的前言中写道: I have heard a number of people over the years voice opinions similar to those of your colleagues. In every case, those opinions could be attributed...

【转】java异常报错大全

算术异常类:ArithmeticExecption 空指针异常类:NullPointerException 类型强制转换异常:ClassCastException 数组负下标异常:NegativeArrayException 数组下标越界异常:ArrayIndexOutOfBoundsException 违背安全原则异常:SecturityExceptio...

【Python之路】特别篇--ECMA对象、DOM对象、BOM对象

ECMA对象从传统意义上来说,ECMAScript 并不真正具有类。事实上,除了说明不存在类,在 ECMA-262 中根本没有出现“类”这个词。 ECMAScript 定义了“对象定义”,逻辑上等价于其他程序设计语言中的类。 var o = new Object(); 对象的概念与分类: 由ECMAScript定义的本地对象.独立于宿主环境的 ECMAS...

JS- 数组去重方法整理

【indexOf】 简单而且可以加中文,但是兼容性不好,indexOF兼容到ie9 1 function uniq(arr) { 2 var temp = []; 3 for (let i = 0; i < arr.length; i++) { 4 if (temp.indexOf(arr[i]) ==...

C++ Primer学习笔记

目录 12.1 动态内存与智能指针 12.1.1 shared_ptr类 12.1.2 直接管理内存 12.1.3 shared_ptr和new结合使用 12.1.4 智能指针和异常 12.1.5 unique_ptr 12.1.6 weak_ptr 12.2 动态数组 12.2.1 new和数组 12.2.2 alllocator类...

使用antd Table + mobx 处理数组 出现的一系列问题

在store中定义了一个数组: @observable list = [...] 若是在table组件中直接使用list: <Table className={styles.table} columns={this.columns} dataSource={list}  /> 这时就会提示以下错误...