《面向对象的思考过程(原书第4版)》一1.10 多态

简介: 多态是一个希腊词,字面上理解为许多形状。尽管多态与继承是紧耦合的关系,但它通常单独作为面向对象技术中最强大的优点之一。当向一个对象发送一个消息时,该对象必须定义一个方法来响应这个消息。在继承体系图中,所有的子类从它们的超类中继承接口。

本节书摘来自华章出版社《面向对象的思考过程(原书第4版)》一书中的第1章,第1.10节,[美] 马特·魏斯费尔德(Matt Weisfeld) 著黄博文 译更多章节内容可以访问云栖社区“华章计算机”公众号查看。

1.10 多态

多态是一个希腊词,字面上理解为许多形状。尽管多态与继承是紧耦合的关系,但它通常单独作为面向对象技术中最强大的优点之一。当向一个对象发送一个消息时,该对象必须定义一个方法来响应这个消息。在继承体系图中,所有的子类从它们的超类中继承接口。然而,由于每个子类是单独的实体,每个子类需要对同一个消息有单独的应答。
例如,Shape类有名为Draw的行为。当你告诉某人画一个形状时,你被问到的第一个问题是“什么形状?”。没人能绘制一个形状,因为形状是一个抽象概念(事实上Shape代码中的Draw()方法并不包含实现)。你必须指定一个具体的形状。比如你需要为Circle提供具体的实现。虽然Shape有一个Draw方法,但Circle继承了该方法并提供了对该方法的实现。重载(overriding)的基本释义是子类覆盖父类中的一个实现。
例如,假设你有Circle、Square和Star三个形状组成的数组。尽管你把它们都当作Shape对象,并为每个Shape对象都发送一个Draw消息,但最终结果是每个图形都是不一样的,因为Circle、Square和Star提供了各自的具体实现。总之,每个类能够对同一个Draw方法返回不同的响应来绘制自己。这正是多态的意义。
Shape类的代码如下所示:
_9
Shape类有一个名为area的属性,它保存了形状的面积。getArea()方法具有一个abstract修饰符。如果方法被定义为abstract,子类必须提供该方法的实现。在本例中,Shape要求子类提供getArea()的实现。现在创建一个名为Circle的类并继承自Shape(extends关键字指定了Circle继承自Shape):
_10

我们引入了一个名为构造函数(constructor)的新概念。Circle类有一个同名的方法Circle。如果方法名与类名相同,并且没有返回值,这个方法就是一个特殊的方法,称为构造函数。可以认为构造函数是类的入口,对象在这里被构造。构造函数里可以进行初始化操作和执行一些启动任务。
Circle构造函数接收单个参数。这个参数代表半径,并且赋值给Circle类的radius属性。
Circle类也提供了getArea方法的实现,而在Shape类中getArea是个抽象方法。
我们创建了一个名为Rectangle的相似的类:

_11
现在我们可以创建任意数量的矩形和圆,只需调用它们的getArea()方法即可。这是因为我们知道所有的矩形和圆都继承自Shape,所有的Shape类都有getArea()方法。如果子类继承了父类的一个抽象方法,它必须提供该方法的具体实现,否则它自身也必须是个抽象类(请看图1-18的UML图)。这种方式提供了快速创建其他新类的机制。


f3323044992749d3a465e07e2d48801155ed7aed



我们可以使用以下方式来实例化Shape类:
_14

什么是栈
栈是一种数据结构,表示一个后进先出的系统。它像一个自动换币器,你把硬币插入圆柱的最上头,当你需要硬币时,则从最上头拿,即拿的是最后一次放入的硬币。将一个东西推入栈意味着你把该东西加入了最顶端(比如将一个硬币插入自动换币器中)。从栈中取一个东西意味着你拿走了最近一次放入栈的东西(比如从最顶处取硬币)。
接下来是最好玩的部分。我们可以清空栈,而不用担心栈中存入了哪种Shape类(我只需知道它们都是形状):
_12
实际上,我们对所有形状发送了相同的信息:
_13
然而产生的实际行为取决于形状类型。例如,Circle计算的是圆的面积,而Rectangle计算的是矩形的面积。实际上,我们给Shape类发送了一个消息,而期望根据使用的Shape子类类型来返回不同的行为。这体现了多态的关键概念。
这种方式就是为类之间(以及应用程序之间)提供标准化的接口。比如办公套件应用程序包含一个文字处理应用和一个电子表格应用。假设这两个都有一个名为Office的类,包含一个名为print()的接口。办公套件中的所有类都要实现print()接口。有意思的是尽管文字处理和电子表格都调用print()接口,但它们会做不同的事情,一个打印文字处理文档,另一个打印电子表格文档。

相关文章
|
5月前
|
Java
Java面向对象编程,解释封装、继承和多态的概念。
Java面向对象编程,解释封装、继承和多态的概念。
40 2
|
9月前
|
存储 编译器 C++
C++ 面向对象三大特性——多态
面向对象三大特性的,封装,继承,多态,今天我们研究研究C++的多态。
|
9月前
|
存储 编译器 C++
【C++】多态及原理
【C++】多态及原理
28 0
|
10月前
再次理解多态概念
再次理解多态概念
42 0
|
10月前
|
设计模式
代码学习-多态
代码学习-多态
34 0
|
10月前
|
Java C++
面向过程、基于对象、面向对象、分析
面向过程、基于对象、面向对象、分析
46 0
面向过程、基于对象、面向对象、分析
|
10月前
|
存储 设计模式 算法
03-📝C++核心语法|面向对象1【 C++编程规范、类和对象、面向对象程序设计案例、对象的构造和析构、C++面向对象模型初探】
复习`C++核心语法`,且适当进行汇编探索底层实现原理,进一步夯实基础,为以后的`底层开发`、`音视频开发`、`跨平台开发`、`算法`等方向的进一步学习埋下伏笔。
03-📝C++核心语法|面向对象1【 C++编程规范、类和对象、面向对象程序设计案例、对象的构造和析构、C++面向对象模型初探】
面向对象程序设计第九章:多态
面向对象程序设计第九章:多态
91 0
理解面向对象特性之多态
多态性是面向对象编程的又一个重要特征,它是指在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为,这使得同一个属性或方法在父类及其各个子类中具有不同的含义。
125 0