这里有一个ruby多级继承的例子,这里我们有3个类A,B和C。B继承自A,C继承自B,所以最后类C拥有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 是一样的,这里不是类 A 和 B,我们有模块 A 和 B,它们被包含到类 C 中。现在类 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]
最后,如果我们以两种方式实现,类 C 将拥有类 A 和 B 或模块 A 和 B 的所有方法。那么为什么使用模块而不是类的多级继承更好呢?
我知道我们应该使用 mixins 但真的不知道为什么我们不应该像上面那样使用多级继承。有什么缺点和优点。如果有的话?
最佳答案
两个主要原因:
您只能继承一个类,但您可以根据需要混入任意多个混入。这意味着继承是极其“昂贵”的,因为如果您被迫使用继承,您将被迫“用完”100% 的“继承资源”。
您可以以任何您想要的方式组合混合。在你的例子中,我只能得到A
的方法,A
的方法∪B
,A<的方法
∪ B
∪ C
。例如,我不能只获取 B
的方法。使用 mixins,我可以将它们组合成任意组合:只有 A
,只有 B
,只有 C
,A
∪ B
、A
∪ C
、B
∪ C
和 A
∪ B
∪ C
。我还可以按照我想要的任何顺序组合它们:我可以让 C
的方法覆盖 B
的方法,或者我可以让这些方法B
重写了 C
的方法。
我可以很容易地想象一个既是 Enumerable
又是 Comparable
的对象。 (例如,String
是 Comparable
和 before Ruby 1.9, they also used to be Enumerable
。)在您提出的世界中,只有 Enumerable
继承自 Comparable
或Comparable
继承自Enumerable
。但是,这将不起作用:Numeric
是Comparable
但不是Enumerable
,Array
是Enumerable
但不是Comparable
.
还有一个更哲学/语义上的原因:可枚举性和可比性是完全正交的概念,为什么要将它们紧密地联系在一起?继承是我们拥有的最接近的耦合形式之一,将两个实际上彼此没有任何关系的概念紧密地联系在一起,这是错误的。
关于ruby - 使用多级继承而不是 ruby mixins,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58032081/