Jun'uary

多重继承

Jan 发表于 2007-10-24 14:01:04

忽然又有了一个恍然大悟的想法,那就是ruby对多重继承的设计真的很棒~

C++中的菱形继承一直被人抓着打,郁闷啊。比如说A派生出B, C, D多继承自B, C,那么,D里面会有两个A的核 - 双核,我已经忘记了C++是禁止这种继承的还是就让两个A同时存在与D里面(印象中是第二种处理吧)。曾经读到过一篇清华的博士论文,建议加入虚继承来处理菱形继承的问题,注意他所提出的虚继承并不是现在正在用的虚继承,而是改变现有的虚继承的语意,表明是一个菱形继承,详细我也不说了,忘光了,sigh

Java采取了一个更加SB的方法,在我看来还不如学C++。Java做出两个决定:一是继承只能有一个父类,二是加入Interface。这种设计直接导致在需要多继承的场合让程序民工们烦的要死,你不要告诉我那是我的设计有问题,你为什么不觉得是Java设计有问题?陷入一堆class abstract class interface之中想要理出一个完美的继承体系的时候真是感觉生不如死,这种麻烦大大削弱了面向对象的能力,完全是历史的倒退。

Ruby, 啧啧,Ruby,非常聪明的引进了一个新的东西,Module,是的,Ruby也限制你只能继承自一个父类,但是你可以无限制的include Module。当你第一眼看到它的时候也许会觉得Module和C里面的MACRO好像,然后把它忘在脑后,可是实际上Module是一个更加面向对象更加高明的设计,它的作用其实是把多重(树形)继承自动的转化成单(链式)继承,当你想要D继承自B, C时,C++/Java的继承图像是这样的:

B  ->
             D
C  ->

Ruby是这样的

B -> C -> D

这里假设我们把C设计为Module。当你include C的时候,c代码会为你创建一个新类,它拥有Module的所有实例变量和方法,同时以B作为这个新类的父类,然后再把D的继承指针指向这个新的类,我们称之为C'好了。这样D就同时拥有了B和C的方法。

在菱形继承的时候,我们把A, B, C都设计为Module, 即B inlucde A, C include A,然后class D include B, C。在Ruby中Module实际上是Class的父类,但Module本身也是一个Class。。。有点绕口。。。Module除了不能在Ruby的层次上被实例化以外,其他和Class并无太大区别。所以这样的设计并没有什么怪异的。最后我们的菱形继承会成为这样:

A->B'->C'->D

由于Module不能实例化,这必然使得Ruby需要另外一个设计,弱类型以及Duck typing。要在c++里面使用多态,你必须这样int lala(A a),也就是用父类来做占位符,如果Ruby也要这样就完了:既然Module不能实例化,那用什么来做占位符?所以Ruby是弱类型, 你def lala(a)就好了,不用声明a是什么类型,只要a有A的方法,我们就认为它是A的实例,这样多态(Duck Typing)就成为很容易的事情了。

不要觉得弱类型有什么不好,真的,利远大于弊。
关键词(Tag): ruby module 多重继承

曾经的这一天...
  • » 2006年: Pi


收藏: QQ书签 del.icio.us 订阅: Google 抓虾

最新评论


  • 菜啊..
    2007-12-13 02:57:07 匿名 221.218.*.*

    LZ不是没想法, 但是想法太单纯.. 只能说你干的那些工作适合弱类型罢了...

  • Jan
    Jan
    2007-12-14 03:33:54

    帅哥,我干的哪些工作?


  • blackanger
    2007-12-23 17:05:40 匿名 221.219.*.*

    由于Module不能实例化,这必然使得Ruby需要另外一个设计,弱类型以及Duck typing

    请问,这有什么必然性??

  • Jan
    Jan
    2007-12-24 01:32:01

    没有Duck Typing, Ruby怎么利用多态? 前面说过mixin实际上是一种继承,ruby中B mixin了module A相当于Java中B extend了A.在Java中我们可以写void func(A a)来利用多态,可以把B的对象传进去;但是在ruby里面不能这样写,因为B mixin A的时候,ruby创造了一个拥有类A所有方法的新类A', B是A'的子类而不是A的子类,所以你不能写void func(A a), 由于A'是ruby内部的类,在ruby外面是看不到的,所以你也没办法写void func(A' a). 但是只要设定成弱类型,引入duck typing,这个问题根本就不存在了,因为现在只需要写作void func(a).

发表评论

* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 
 

分类小组论坛
杂谈, 娱乐、八卦, 文学、艺术, 体育, 旅游、同城, 象牙塔, 情感, 时尚、生活, 星座, 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定

Jan'uary

人类一思考,老夫就发笑

搜索

日历