敲响OO时代的丧钟!——继承、重用、多态 OO交通编程生活生物
OO的核心思想就是继承,那么,OO为什么要继承呢?对于这个问题,OO的理论大师们有好多个版本的解释:
1、“这是OO的类型系统自然的要求。设想一下生物学的分类系统:动物——>哺乳动物——>灵长类动物——>人类。或者设想一下我们的概念系统:机器——>交通工具——>汽车——>小轿车。这样的现象在你的生活中难道不是随处可见吗?”
2、“如果你有一个类,叫做车辆,这个车辆类能够移动,现在你要建立一个子类,叫做家庭型轿车,你就可以直接继承车辆这个类,而不需从头再写移动部分的代码了呀!”
3、“如果你有三个类,三角形、四边形、正方形,他们都需要显示在屏幕上,那么你就可以建立一个基类叫多边形,提供一个draw()方法,然后让那个三个类都继承这个多边形类并且覆盖那个draw()方法,这样,你就可以在绘图的时候,统一对一种多边形类进行操作,不用去管那个对象究竟是哪一种多边形。”
这三种解释,是最为典型的OO继承的好处的解释了。但是你如果仔细的看,就能发现这三种好处,分别描述的是:“概念的特化”、“代码的重用”以及“接口的重用”。或者可以分别命名为:“继承”、“重用”、“多态”。
“这样有什么问题吗?”,也许有人会问。问题就出在这三个好处是用一种方法提供,而这三个好处相互之间有时是相通的,有时又是矛盾的!当我们运用OO语言,来写这样的继承的语句时,一切都是“搅和在一起的”!
假设Class A有两个属性和两个方法:String a1;int i;void f1();void f2();当我们另外写一个Class B去继承Class A的时候,我们可以继续使用某些属性,而覆盖另一些属性,还可以继续使用某些方法,而重写另一些方法。还可以添加一些新的属性,还可以添加一些新的方法。如果在加上各种访问控制符的限定与修正。谁能够告诉我:“这个Class B究竟想干什么?!”
也许有人会继续为这样的现象辩解:“这是对于继承的误用,正确的OO程序不会这样的!”
但是,这个辩解并不成立,几乎所有的OO的编程语言,都没有在继承问题上做出太多“非此即彼”的限制,原因只有一个,那就是,在某些特定的场合,这样的“拼盘”是相对最合理的编码方式。
我们前面还没有提到多重继承,一个允许多重继承的语言,会让这个问题更为复杂,也可以说会使得场面越发的混乱。让我们举一个例子,这是Eiffel语言的继承语法,让我们看一看面对继承这样一件事情,一个程序员,究竟需要考虑多少问题。来源是《对象揭密》,我就一边抄,一边直接翻成中文了。
继承 :inherit 父类列表
父类列表 :{父类 ";" ... }
父类 :类名[特性适配说明]
特性适配说明:[Rename] :重命名以消除名字冲突
[New_exports] :重新设定特性导出的分组
[Undefine] :撤销定义
[Redefine] :重定义以取代虚函数
[Select] :更加高级的功能
end
最值得看的就是这个特性适配说明,更加深入的说明还是各位自己去找书看吧。这就是号称优雅的解决了OO继承问题的Eiffel语言。他所谓的优雅,可以不客气的说,就是把所有的麻烦都明确的告诉你,而不是像C++和Java那样,假装什么事情都没有发生过。但是,麻烦依然在那里,并没有减少,根本的解决方法,是应该不让这样的麻烦出现呀!可是OO确实无法做到这一点。
因为他把数据和操作封装在了一起,然后又偷换了实体本质的概念,在这样的情况下的OO,他的继承是肯定搞不好的!
(未完待续)
上一篇: 科学造假 - 中国人的羞耻
下一篇: 新手熄火分析,记录成长过程 交通