看板CompBook
标 题Re: 继承的特性 ??
发信站清华资讯(枫桥驿站) (Sun Apr 16 13:46:01 2000)
转信站Ptt!bbs.ee.ntu!freebsd.ntu!news.cs.nthu!maple
【Re: 继承的特性 ??】
侯捷
[email protected]
http://www.jjhou.com
2000.04.16 第一次发表於
清大.枫桥驿站(140.114.87.5).物件导向版(Computer/oop)
本文将於日後整理於 侯捷网站/散文 2000
----------------------------------------------------------------
这里有一封 BBS/News OOP 版的贴信,引起我的兴趣。
原信如下:
-------------------------------------------↓
发信人:
[email protected] (自是温柔最伤人), 看板: oop
标 题: Re: 继承的特性 ??
发信站: 元智大学风之塔 (Wed Apr 12 22:01:15 2000)
> >有时继承的使用,并不遵守现实上的观念
> >例如:
> >圆是一种椭圆
> >所以继承时,应该要先写一个椭圆
> >然後写一个圆去继承椭圆
> 这种继承的方式有可能会违反 Liskov-Substitution Principle
> >所以 椭圆 比 圆 多了一个 data member
> >故我们会写成
> >椭圆继承了圆
> 这种方式只是为了继承圆的 implementation 更是错误示范.
> 既然椭圆不是圆就不该继承圆.
> 在这个情形下最好圆跟椭圆不要互相继承, 但可以让两者
> 有一个共同继承的 base class.
恩...王虫兄所言甚是
当初上 侯 Sir 开的课时, 就觉得他举这个例子怪怪ㄉ
但一直找不到什麽说法来解释
现在总算一语道破了说
也就是说
继承树就会变成
Shape
|
-------------------
| |
Basic Rect Basic Ellipse
| |
-------------- ----------------
| | | |
Rect Square Circle Ellipse
恩恩恩恩.....
可是这样会不会增加管理的复杂度啊....
---------------------------------------------↑
以下是侯捷的感想:
1. 上课教学所举例子,有时候视当时使用时机(是否为主讲重点,
或只是为了有个继承体系以做其他讲题用途)、讲课对象的程度
(是否有一半以上的人从未听闻所谓 interface inheritance),
而有不同深度的讨论。如有同学程度超过老师的预期,宜於上课或
下课继续追问疑点,可避免让自己的疑惑一直成为疑惑。
2. 《多型与虚拟》书中亦曾举过类似上述「以椭圆继承圆」的例子,
确属粗糙。然亦不可能於当时剖析 implementation inheritance 和
interface inheritance 的区别。因为当时的情况是希望给一个
「尽量简化」的继承体系,以做为「多型」之操练对象。
3. 粗糙就是粗糙,所以比较好的作法是在举「以椭圆继承圆」的例子
时,加注少量补充说明与提醒。我将於《多型与虚拟》2/e 中这麽做。
4. inheritance 是个复杂的题目,涵盖 public/protected/private
base classes,virtual/nonvirtual base classes;virtual/nonvirtual
member functions。欲厘清所有这些观念,以网路上的简短讨论做为
学习之道并非智举。最佳办法就是找一本好书。
5. 推荐一本好书:Effective C++ 2/e,其中有一章专论
「继承机制与物件导向设计(Inheritance and Object-Oriented Design)。
内容包括:
---------------------------------------------↓
条款35:确定你的 public inheritance 模塑出 "isa" 的关系
Item 35: Make sure public inheritance models "isa."
条款36:区分「介面继承(interface inheritance)」和
「实作继承(implementation inheritance)」
Item 36: Differentiate between inheritance of interface and
inheritance of implementation.
条款37:绝对不要重新定义一个继承而来的非虚拟函式
Item 37: Never redefine an inherited nonvirtual function.
条款38:绝对不要重新定义一个继承而来的预设参数值
Item 38: Never redefine an inherited default parameter value.
条款39:避免在继承体系中做 cast down(向下转型)的动作
Item 39: Avoid casts down the inheritance hierarchy.
条款40:透过 layering(分层技术)来模塑 has-a 或
is-implemented-in-terms-of 的关系
Item 40: Model "has-a" or "is-implemented-in-terms-of"
through layering.
条款41:区分 inheritance 和 templates
Item 41: Differentiate between inheritance and templates.
条款42:明智地运用 private inheritance(私有继承)
Item 42: Use private inheritance judiciously.
条款43:明智地运用多重继承(multiple inheritance,MI)
Item 43: Use multiple inheritance judiciously.
条款44:说出你的意思并了解你所说的每一句话
Item 44: Say what you mean; understand what you're saying.
---------------------------------------------↑
6. 在「正方形和矩形」(或是椭圆形和圆形)的继承关系上,
Effective C++ 2/e item35 有这样的叙述(摘录):
---------------------------------------------↓
p158~p160 :
或许你会说,你对於鸟类实在缺乏直觉,但是你的几何学学得不错。
喔,是吗?我想说的是,正方形和矩形之间可能有多麽复杂?
好,请你回答这个问题:class Square 应该以 public 的方式继承
class Rectangle 吗?
图
『咄!』你说,『当然应该如此!每一个人都知道正方形是一种矩形,
反之则不一定』。这是真理,至少高中数学课本是这麽教的。但是我
不认为你现在还是高中学生。
考虑这份码:
....
现在再考虑这份码,其中使用 public inheritance,允许正方形
被视为一种矩形:
....
欢迎来到 public inheritance 的奇异世界。你在其他领域(包括数学)
学习而得的直觉,在这里恐怕无法如预期般地有所表现。本例的根本困难
是,某些事情可施行於矩形身上(例如宽度可单独被修改),却不可施行
於正方形身上(其宽度总是应该和高度一样)。但是 public inheritance
主张,每一件事情只要能够施行於 base class objects 身上 —
每件事情唷! — 就一定可以施行於 derived class objects 身上。
在正方形和矩形的例子中(另一个类似的例子是 sets 和 lists,见条款40),
那样的主张无法保持,所以以 public inheritance 来模塑它们之间的
关系是错误的。编译器会让你通过,但是一如我们所见,这并不保证程式
的行为适当(或正确)。每个程式员都必须学得一个教训:程式码通过
编译,并不表示就可以正确运作。
现在,不要因为你发展经年的软体直觉在与物件导向观念
打交道的过程中失去效用,便心慌意乱起来。那些知识
还是有价值的,但现在你已经为你的军械库加上 inheritance(继承)
这支大炮,你也必须为你的直觉添加新的洞察力,以便引导你适当地运用
inheritance 这支神兵利器。当有一天有人展示一个数页长的函式给你看,
你终将回忆起「令 Penguin 继承 Bird,或是令 Square 继承 Rectangle」
的概念和趣味;这种继承方式有可能接近事实真象,但也有可能不是。
是的,当然,「是一种(isa)」并不是唯一存在於 classes
之间的关系。另两个常见关系是「有一个(has-a)」和「根据
某物实作出(is-implemented-in-terms-of)」。这些关系将在
条款40和42讨论。将上述这些重要的相互关系中的任何一个误塑
为 isa 而造成的错误设计,在 C++ 中实不罕见,所以你应该
确定你确实了解这些「classes 相互关系」间的差异,并且知道
在 C++ 中如何塑造它们。
---------------------------------------------↑
-- the end
--
※ Origin: 枫桥驿站<bbs.cs.nthu.edu.tw> ◆ Mail: [email protected]