给定A类和B模块,混合B的实例方法,使其覆盖A的相应实例方法。
module B
def method1
"B\#method1"
end
def method2
"B\#method2"
end
end
class A
def method1
"A\#method1"
end
def method2
"A\#method2"
end
# include B does not override instance methods!
# (module gets mixed into the superclass)
end
puts A.new.method1 # want it to print out "B#method1"
puts A.new.method2 # want it to print out "B#method2"
答案 0 :(得分:7)
Module#include
将模块M
作为类C
的超类插入。因此,您无法覆盖C
中的M
方法,而是相反:C
的方法会覆盖M
的方法。 (从技术上讲,Ruby不会使M
成为C
的超类,而是创建一个不可见的包含类 ⟦M′⟧
,其方法表和常量表指向M
的方法表和常量表,并使那个类成为超类,但这种区别对于这个特定的问题并不重要。)
在Ruby 2.0中,有一种新方法Module#prepend
,正如其名称所示,预先 M
到C
的祖先,换句话说,使M
成为C
的子类。
所以,简而言之:你不能,至少现在还没有。
答案 1 :(得分:0)
在加入B
之前,您可以从A
删除B
个方法。
class A
def method1
"A\#method1"
end
def method2
"A\#method2"
end
B.instance_methods(false).each { |method|
remove_method(method) if instance_methods(false).include?(method)
}
include B
end
或者来自B
:
module B
def method1
"B\#method1"
end
def method2
"B\#method2"
end
def self.append_features(mod)
instance_methods(false).each { |method|
mod.send(:remove_method, method) if mod.instance_methods(false).include?(method)
}
super
end
end