使用多级继承而不是 ruby mixins

Using multi-level inheritance instead of ruby mixins

这里有一个多级继承的例子ruby,这里有3个classA,B,C,B继承A,C继承B,所以在最后classC有A、B、C的所有方法

class A
  def hello_by_a
    puts "A says hello"
  end
end

class B < A
  def hello_by_b
    puts "B says hello"
  end
end

class C < B
  def hello_by_c
    puts "C says hello"
  end
end

c = C.new
c.hello_by_a #=> A says hello
c.hello_by_b #=> B says hello
c.hello_by_c #=> C says hello

p c.methods-Object.methods #=> [:hello_by_c, :hello_by_b, :hello_by_a]

这和 mixin 是一样的,这里不是 classes A 和 B,我们有模块 A 和 B,它们包含在 class C 中。现在 class C 有所有 3 种方法

module A
  def hello_by_a
    puts "A says hello"
  end
end

module B
  def hello_by_b
    puts "B says hello"
  end
end

class C
  include A
  include B

  def hello_by_c
    puts "C says hello"
  end
end

c = C.new

c.hello_by_a #=> A says hello
c.hello_by_b #=> B says hello
c.hello_by_c #=> C says hello

p c.methods-Object.methods #=> [:hello_by_c, :hello_by_b, :hello_by_a]

最后如果我们两种方式都做 class C 将拥有 class A 和 B 或模块 A 和 B 的所有方法。那么为什么使用模块更好呢? classes?

的多级继承

我知道我们应该使用 mixins 但真的不知道为什么我们不应该像上面那样使用多级继承。有什么缺点和优点。如果有的话?

两个主要原因:

您只能继承一个 class,但您可以根据需要混入任意多个混入。这意味着继承是极其 "expensive" 的,如果你被迫使用继承,你将被迫 "use up" 100% 的 "inheritance resources".

您可以按照自己的方式编写混合宏。在你的例子中,我只能得到A的方法,A的方法∪BA的方法∪BC。例如,我不能只获取 B 的方法。使用 mixin,我可以将它们组合成任意组合:仅 A、仅 B、仅 CABACBCABC。我也可以按照我想要的任何 顺序 组合它们:我可以让 C 的方法覆盖 B 的方法,或者我可以让 B 覆盖 C.

的方法

我可以很容易地想象一个既是 Enumerable and Comparable. (For example, Strings are Comparable and before Ruby 1.9, they also used to be Enumerable.) In your proposed world, this would only be possible if either Enumerable inherits from Comparable or Comparable inherits from Enumerable. However, this will not work: Numerics are Comparable but not Enumerable, Array 又是 Enumerable 但不是 Comparable 的对象。

还有一个更哲学/语义的原因:可枚举性可比性是完全正交的概念,为什么你把他们绑的这么紧?继承是我们拥有的最接近的耦合形式之一,将两个实际上彼此没有任何关系的概念紧密地联系在一起,只是错误