C++批判系列5--继承的本质

转载 2007年09月14日 08:56:00

继承的本质

继承关系是一种耦合度很高的关系,它与组合及一般化(genericity)一样,提供了OO中的一种基本方法,用以将不同的软件组件组合起来。一个类的实例同时也是那个类的所有的祖先的实例。为了保证面向对象设计的有效性,我们应该保存下这种关系的一致性。在子类中的每一次重新定义都应该与在其祖先类中的最初定义进行一致性检查。子类中应该保存下其祖先类的需求。如果存在着不能被保存的需求,就说明了系统的设计有错误,或者是在系统中此处使用继承是不恰当的。由于继承是面向对象设计的基础,所以才会要求有一致性检测。C++中对于非虚拟函数重载的实现, 意味着编译器将不会为其进行一致性检测。C++并没有提供面向对象设计的这方面的保证。

继承被分成"语法"继承和"语义"继承两部分。Saake等人将其描述如下:"语法继承表示为结构或方法定义的继承,并且因此与代码的重复使用(以及重写被继承方法的代码)联系起来。语义继承表示为对对象语义(即对象自己)的继承,。这种继承形式可以从语义的数据模型中被得知,在此它被用于代表在一个应用程序的若干个角色中出现的一个对象。"[SJE 91]。Saake等人集中研究了继承的语义形式。通过是行为还是语义的继承方式的判断,表示了对象在系统中所扮的角色。
 
然而,Wegner相信代码继承更具有实际的价值。他将语法与语义继承之间的区别表示为代码和行为上的区别[Weg 91](p43)。他认为这样的划分不会引起一方与另一方的兼容,并且还经常与另一方不一致。Wegner同样也提出这样的问题:"应该怎样抑制对继承属性的修改?"代码继承为模块化(modularisation)提供一个基础。行为继承则依赖于"is-a"关系。这两种继承方式在合适处都十分有用。它们都要求进行一致性的检测,这与实际上的有意义的继承密不可分。

看起来在语义保持关系中那些限制最多的形式中,继承似乎是其中最强的形式;子类应该保存祖先类中的所有假设。

Meyer [Meyer 96a and 96b]也对继承技术进行了分类。在他的分类法中,他指出了继承的12种用法。这些分析也给我们怎么使用继承提供了一个很好的判断标准,如:什么时候应该使用继承,什么时候不应该它。

软件组件就象七巧板一样。当我们组装七巧板时,每一块板的形状必须要合适,但更重要地是,最终拼出的图像必须要有意义,能够被说得通。而将软件组件组合起来就更困难了。七巧板只是需要将原本是完整的一幅图像重新组合起来。而对软件组件的组合会得到什么样的结果,是我们不可能预见到的。更糟的是,七巧板的每一块通常是由不同的程序员产生的,这样当整个的系统被组合起来时,对于它们的吻合程度的要求就更高了。

C++中的继承像是一块七巧板,所有的板块都能够组合在一起,但是编译器却没有办法检测最终的结果是否有意义。换句话说,C++仅为类和继承提供了语法,而非语义。可重用的C++函数库的缓慢出现,暗示了C++可能会尽可能地不支持可重用性。相反的是,Java,Eiffel和Object Pascal都与函数库包装在一起出现。Object Pascal与MacApp应用软件框架联系非常紧密。Java也从与Java API的耦合中解脱出来,取而代之的是一个包容广泛的函数库。Eiffel也同样是与一个极其全面的函数库集成在一起,该函数库甚至比Java的还要大。事实上函数库的概念已经成为一个优先于Eiffel语言本身的工程,用以对所有在计算机科学中通用的结构进行重新分类,得到一个常用的分类法。[Meyer 94].

 

C++批判系列5--继承的本质

继承的本质继承关系是一种耦合度很高的关系,它与组合及一般化(genericity)一样,提供了OO中的一种基本方法,用以将不同的软件组件组合起来。一个类的实例同时也是那个类的所有的祖先的实例。为了保证...
  • cber
  • cber
  • 2001年06月09日 15:59
  • 1449

对C++继承,封装,多态的理解

C++用了一段时间,感觉对C++慢慢的有了一点了解,在这和大家分享一下。 C++是一款面向对象的语言,拥有面向对象语言的三大核心特性:继承,封装,多态。每一个特性的良好理解与使用都会为我们的编程带来莫...
  • u011675242
  • u011675242
  • 2013年08月29日 17:38
  • 2310

iOS开发中关于继承、扩展和协议的理解

OC中protocol、category和继承的区别以前还是有点迷糊,面试的时候说的有点混乱,现在结合一些资料总结一下。 利用继承,多态是一个很好的保持“对扩展开放、对更改封闭”(OCP)的办法...
  • yuanyuan1314521
  • yuanyuan1314521
  • 2016年05月11日 10:40
  • 1071

C#高级编程系列(共13个文件)-5

  • 2011年04月25日 16:28
  • 15.23MB
  • 下载

数据结构学习系列二-链表的C++实现

1 先定义一个链表的结构体(1)包括数据 int data(2)下一个节点 Node*Next2 定义一个链表类#include using namespace std; /*单向链表head为头...
  • dinghu721521
  • dinghu721521
  • 2011年05月25日 15:26
  • 330

数据结构学习系列三-单向循环链表(c++实现且应用模板)

单向循环链表且带模板的实现真正意义上c++实现节点数据结构采用class形式,为了方便操作数据结构用public。#include using namespace std; /*1 应用模板 2使...
  • dinghu721521
  • dinghu721521
  • 2011年05月25日 16:32
  • 1270

C / C++算法学习笔记(5)-选择法

原始地址:C / C++算法学习笔记(5)-选择法   选择法:         现在我们终于可以看到一点希望:选择法,这种方法提高了一点性能(某些情况下)这种方法类似我们人为的排序习惯:  ...
  • shiyiyufen
  • shiyiyufen
  • 2013年06月03日 22:33
  • 2061

细究lua闭包->搞清本质才是王道

Lua中的函数是一阶类型值(first-class value),定义函数就象创建普通类型值相同(只不过函数类型值的数据主要是一条条指令而已),所以在函数体中仍然能定义函数。假设函数f2定义在函数f1...
  • jiang_bing
  • jiang_bing
  • 2013年08月17日 23:17
  • 576

【转】细究lua闭包->搞清本质才是王道

细究lua闭包->搞清本质才是王道 Lua中的函数是一阶类型值(first-class value),定义函数就象创建普通类型值相同(只不过函数类型值的数据主要是一条条指令而已),所以在...
  • weiyuefei
  • weiyuefei
  • 2014年07月19日 23:25
  • 806

深入C++ Builder之编写自己的元件-深入分析VCL继承、消息机制

这篇文章提及内容可能大家已经在很多地方看到过了,作者也是如此,只不过还看了很多VCL源代码,加上自己实际编写元件的经验,拼凑了这么一篇文章。所以所有言论都是个人观点、经验的描述,仅供参考。 你可转载...
  • zb872676223
  • zb872676223
  • 2014年10月27日 23:38
  • 657
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++批判系列5--继承的本质
举报原因:
原因补充:

(最多只允许输入30个字)