考虑来自this article的代码:
class Coffee
def cost
2
end
end
module Milk
def cost
super + 0.4
end
end
module Sugar
def cost
super + 0.2
end
end
coffee = Coffee.new
coffee.extend(Milk)
coffee.extend(Sugar)
coffee.cost # 2.6, while I expected 2.2
它的2.6而不是2.2的原因是因为extend
的每次调用都会在实例单例类祖先链中添加一个模块,如下所述。
答案 0 :(得分:2)
extend
添加到祖先列表中,它不会替换任何现有的祖先 - 如果您在第二次扩展后检查coffee.singleton_class.ancestors
,则可以看到它包含Milk
和{ {1}}。
如果您运行的是2.2,则可以使用新的Sugar
方法来检查:
super_method
这表明如果你称'成本',你首先要去'糖'模块的实现
coffee.method(:cost) => #<Method: Coffee(Sugar)#cost>
这表明在coffee.method(:cost).super_method => #<Method: Coffee(Milk)#cost>
中您拨打Sugar#cost
,然后您将跳转到super
提供的方法
最后
Milk
当你从那里调用super时,你最终会进入基类实现
答案 1 :(得分:0)
你总是只有#cost
被未来的争论所修改 - 这不是被覆盖的问题:
coffee = Coffee.new
#cost is 2
coffee.extend(Milk)
#cost is 2.4
coffee.extend(Sugar)
#cost is 2.6
文章说这个实现与它们提供的其他基于继承的示例相同。