欢迎
游客
,
注册
|
登录
|
会员
|
界面
|
简洁版本
|
在线
|
帮助
商都网教育宝典宝库
商都网教育宝典宝库
计算机
等级考试
C++编程批评系列继承的本质
本主题被查看305次, 共1个帖子, 1页, 当前为第
1
页 选择页数: 1 跳转到第
页
上一主题
下一主题
标题: C++编程批评系列继承的本质
huahua
-[尕硴]
超级版主
UID: 71
来自:
精华:
130
积分: 14003
帖子: 12909
注册: 2007-10-22 17:59:00
状态:
离线
威望: 444.00
金钱: 3355.00 元
发短消息
用户资料
树型
回复
引用
只看楼主
2008-01-28 09:16
C++编程批评系列继承的本质
Eiffel和C++都提供了多继承的机制。但Java却没有,因为它认为多继承会导致许多问题的出现。不过Java提供了接口(interface)作为一种替换机制,它类似于Objective C中的协议(protocol)。Sun宣称接口可以提供多继承所能提供的所有特性。
Sun所宣称的“多继承会带来许多的问题”这个观点是对的,尤其是在C++中用以实现多继承的方法更能说明这一点。那些看起来似乎使用多继承会比单继承更简单的理由,现在都以被证明是毫无意义。例如,如何制订对于从两个类之上继承得到的具有相同名字的数据项之间的策略?它们之间是否兼容?如果是的话,那他们是否应该被合并成为一个实体?如果不兼容,那应该如何区分它们?……这样的列表可以列出很长很长。
Java的接口机制也可以用以实现多继承,但它也有一个很重要的不同之处(与C++相比):继承中的接口必须是抽象的。由于使用接口并没有任何的实作,这就消除了需要从不同实作之间选择的可能。Java允许在接口中声明具有常数字段。当需要多继承时,他们就合并成为一个实体,这样也就不会导致歧义的产生。但是,当这些常数具有不同的值时,又有什么会发生呢?
由于Java不支持多继承,我们就不可以像在C++和Eiffel中那样使用混合(mixin)了。混合是一种特性,它可以把从不同的类中得到的不同的非抽象的函数放到一起形成一个新的复杂的类。例如,我们可能希望从不同的源代码中导入一些utility函数。然而,我们也可以通过使用组合而不是继承来达到同样的效果,因此,这也就不会对Java构成一个重要的攻击了。
Eiffel在解决多继承问题时并没有导入一个单独的接口机制。
有些人可能认为,相对于多继承来说,单继承更优雅一些。这是一个很特别的观点。
BETA [Madsen 93]就属于认为“多继承不优雅”的那一种:“Beta中没有多继承,这主要是因为(对于多继承)缺乏一个深刻的理论上的理解,并且当前的(对于多继承的)建议在技术上看来也非常复杂”。他们引用了Flavors(一种可以将类混合在一起的语言)为证据。与Madsen相比,Flavors中的多继承与其顺序有关,也就是说,继承自(A,B)和继承自(B,A)是不一样的。
Ada95是另一种不支持多继承的语言。Ada95支持单继承,并把它叫做标记类型扩展(tagged type extension)。
另外一些人认为,对于某些特殊模型下的问题,多继承可以提供优雅的解法,因此为之付出的努力也是值得的。虽然上面所列出的关于多继承的问题列表并不完善,它仍然显示:与多继承相关的问题是可以被系统地辨识出来的,而一旦问题被确认,它们也就可以被优雅地解决。当[Sakkinen 92]对于多继承研究到达一个很深的程度后,它就得出了上述定义。
Eiffel中采用的方法是,多继承会引发一些有趣的且有挑战性的问题,然后再优雅地解决它们。程序员所需做的所有决定都被限制在类的继承子句中。它包括使用renaming来保证众多从继承中得来的同名特性最终成为具有不同名字的特性,对于继承而来的特性所施展的新的export策略:redefining和undefining,以及用来消除歧义的select。在所有的情况下,编译器都会为我们做好这一切,为了使得语义清晰而不管是选择使用fork或是join,程序员都具有完全的控制权。
C++中相对Eiffel来说有着另外一种不同的用于消除歧义的机制。在Eiffel中,在renames子句中,特性间必须有着不同的名字。在C++中,可以使用域解析操作符’::’来区分成员。Eiffel的做法好处在于,歧义在声明中就被消除掉了。Eiffel的继承子句相对C++的来说要复杂不少,但它的代码也显得更简单,更稳固,并更具弹性。这也就是声明方法与操作符方法相比的好处所在。在C++中,每次当我们碰到在多个成员间具有歧义时,我们必须在代码中使用域解析操作符。这经使得代码变得混乱不堪,影响其延展性,如果有其他地方的改变会影响歧义时,我们可能就需要在歧义可能出现的每个地方改变已有的代码。
依照[Stroustrup 94]中12.8节所说,ANSI委员会考虑过使用renaming,但是这个提议被委员会中的一个成员所阻塞掉了,他坚持让委员会中的其他成员用两周时间来好好地考虑这个问题。在12.8节中给出的例子显示了在没有显示的renaming的前提下,如何做可以得到同样的效果。问题在于,如果这都需要那些专家们使用两周来考虑如何实现,那留给我们的空间又有多少呢?
域解析操作符并不只是被用来消除多继承所带来的歧义。由于设计良好的语言可以避免歧义的出现,因此域解析操作符也就是一个丑陋的,加深复杂性的实作手法。
在C++中,“如何来声明多继承中的父类们”是一个很复杂的问题。它影响到了建构函数被调用的次序,当程序员确实想从子类转到父类时也会导致问题的出现。然而,我们也可以把这个称为不好的程序设计风格。
C++和Eiffel的另一个不同之处在于直接的重复继承,Eiffel中允许:
class B inherit A, A end 但
class B : public A, public A { };
却不被C++认可。
#1
大
中
小
本主题被查看305次, 共1个帖子, 1页, 当前为第
1
页 选择页数: 1 跳转到第
页
论坛跳转...
胎教早教
准备怀孕
怀孕期
出生与分娩
婴儿期(0-1岁)
幼儿期(1-3岁)
学龄前(3-6岁)
中小学
课件
试题
中招
中招动态
招生快讯
相关政策
考试辅导
语文
数学
英语
物理
化学
生物
政治
历史
地理
家长交流
历年中招资料
满分作文
高考
高考动态
高考状元
历年试题
家长必读
志愿填报
心理减压
复习技巧
考生经验
备考辅导
高考大纲
历年分数线
高考常识
高考指南
语文
数学
外语
物理
化学
生物
历史
地理
政治
文综
理综
高考满分作文
家长
教师
读书
作文
郑州新东中学
学校动态
学生天地
高等教育
移民留学
成人高考
自学考试
考研
论文
外语
雅思
托福
四六级
实用英语
职称外语
公共英语(PETS)
商务英语
英语口语
小语种
英思力美语
在线留言
学校动态
课程
学生作业
英思力相册
学英语资料
计算机
办公应用
软件开发
平面动画设计
IT资格认证
等级考试
网络工程
初学者之路视频教程
计算机基础
Windows
Word2003
Execl2003
Powerpoint
Flash
Deamweaver
Fireworks
黑客基础
北大青鸟
青鸟新闻
开班信息
青鸟师资
在线问答
学员相关
技术文章
职业资格
企业培训师
资料库
历年试题
案例探讨
相关政策
财务会计
公务员考试
营养师
营养动态
职业前景
健康权威
学习指导
营养知识
健康食谱
心理咨询师
心理俱乐部
学习指导
花季少年
爱情婚姻
心理障碍
人在职场
职业前景
经典案例
导游
司法考试
建筑工程资格
外贸资格
医药资格考试
教师资格考试
电子商务师
人力资源师
资料库
历年试题
案例探讨
相关政策
技能培养
汽车驾驶
美容美发
美容
美发
化妆
整体形象设计
相关课程
人才信息
茶艺
调酒
厨师烹饪
手机维修
音乐乐器
舞蹈健身
企业管理
人力资源
市场营销
管理激励
管理书籍
管理视频
信诺专栏
职场招聘
招聘信息
职场沙龙
现在的时间是 2008-10-07 18:41:13
版权所有
商都网教育宝典
Powered by
Discuz!NT
1.0.6666 Copyright © 2001-2008
Comsenz Inc
.
Processed in 0.128 seconds