代码之家  ›  专栏  ›  技术社区  ›  horseyguy

Ruby模块包含如何不是真正的“多重继承”,以及Ruby样式如何避免与多重继承相关的问题?

  •  13
  • horseyguy  · 技术社区  · 14 年前

    据推测,Matz说“mixins几乎可以做多重继承所做的一切,而没有相关的缺点”(Matz words)

    首先,为什么Ruby模块包含不是“多重继承”?在我看来,模块和类之间几乎没有区别。当模块用作超类时,不能实例化它的事实是不相关的。

    我还知道,连续的模块包含形成了从类向上延伸的单个继承链(而不是树)。但对我来说,这不足以将它与“多重继承”区分开来,因为Python多重继承系统还“线性化”了超类链(使用 C3 algorithm

    那么,在Python这样的语言中,Ruby模块混合与多重继承究竟有什么区别呢?为什么Python采用c3 MRO算法背后的参数不适用于Ruby呢?如果它们真的适用,为什么Ruby决定不采用这种算法?

    谢谢

    4 回复  |  直到 14 年前
        1
  •  3
  •   A. Wilson    13 年前

    以姆拉丁的名义把这个作为一个实际的答案,因为我发现它非常有用,我猜答案会被索引,无论它做了什么疯狂的事情。

    这是一篇关于那件事的好文章,看看它是否能回答你的问题 问题: http://artima.com/weblogs/viewpost.jsp?thread=246488 Jablanovi 10月28日18:23

        2
  •  4
  •   kikito    14 年前

    多重继承最常见的问题是 Diamond Problem . 如果同一级别上的多个超类定义了同一个方法,您如何知道对子类调用哪个方法?

    对于模块,这个问题很容易解决-最后包含的模块总是“赢”。不能同时包含几个模块,就像C++中的类一样。所以这个问题从来没有出现过。

    当模块用作超类时,不能实例化它的事实是不相关的

    我完全不同意。

    首先,在ruby中模块永远不会被“用作超类”;只有超类才是。

    其次,使用多重继承,确切地知道构造函数(析构函数)的顺序被称为是 not a trivial matter . ruby模块不允许实例化的事实完全消除了这个问题。

        3
  •  0
  •   Derick Bailey    14 年前

    看看实用出版社的“元编程Ruby”一书。它包含了一个非常详细的解释,以一种非常容易阅读和理解的方式。 http://pragprog.com/titles/ppmetr/metaprogramming-ruby

    我不能回答你的任何问题,因为我不懂python。但是为什么它不是多重继承的基本原理是ruby在包含模块或者类被模块扩展时将模块注入继承链。

    class Foo
      include Bar
    end
    
    module Bar
    end
    
    foo = Foo.new
    

    这比这要复杂得多,而且继承注入发生的顺序也有规则。我引用的那本书解释得很好。

        4
  •  0
  •   mpapis    14 年前

    在ruby中,最重要的是用每个包含的模块覆盖以前的数据/函数定义。

    所以这是不好的,因为每个新的模块理论上都应该负责访问被覆盖的以前的代码。

    所以编写新模块的示例代码是(逻辑上):

    old_function = fun
    fun = define_new_function
      do_you_staff
      call old_function
    

    每个包含的模块将构建覆盖方法链,因此多重继承不会有问题,但包含模块的顺序变得更重要。

    这种方法也被称为monkey-patching——Ruby on Rails中广泛使用的术语。