给出两个类
class A
def method_a ()
method_b()
end
def method_b ()
puts "Comes from A"
end
end
和B
继承自A
class B < A
def method_a ()
super()
end
def method_b ()
puts "Comes from B"
end
end
当我致电B.method_a
时,结果将是:Comes from B
。是否有可能告诉A
调用method_b
而不是覆盖我的Comes from A
? (这样结果就是{{1}})
答案 0 :(得分:0)
我不认为你可以直接做到这一点,不会破坏,但不会破坏inheritance
和template pattern
的目的,因为可能有C
}类以及继承自A
,并且您可能只想调用类method_b
的{{1}}函数,因为它已被覆盖并且需要。
答案 1 :(得分:0)
你所要求的不被支持,因为它破坏了继承点。您可以做的是将实现拆分为两个方法 - 一个执行A
实现method_b
,一个不被覆盖,一个委托到该实现,可能被覆盖:
class A
def method_a
dont_override_me
end
def method_b
dont_override_me
end
private
def dont_override_me
puts "Comes from A"
end
end
class B < A
def method_a
super
end
def method_b
puts "Comes from B"
end
end
答案 2 :(得分:0)
class A
def method_a; comes_from_A end
def method_b; puts "Comes from A" end
alias comes_from_A method_b
end
class B < A
def method_a; super end
def method_b; puts "Comes from B" end
end
答案 3 :(得分:0)
您可以按如下方式修改子类:
class B < A
def method_a
self.class.send(:remove_method, :method_b)
super()
self.class.send(:alias_method, :method_b, :method_b_alias)
end
def method_b
puts "Comes from B"
end
alias_method :method_b_alias, :method_b
end
b = B.new
b.method_b
# Comes from B
b.method_a
# Comes from A
b.method_b
# Comes from B
创建子类时会创建别名:method_b_alias
。每当method_a
的实例调用B
时,B
方法method_b
的{{1}}被移除,super
' s A
找不到它并使用自己的method_a
代码(因为method_a
的{{1}}(A
)的接收者是{{method_a
的实例1}}。)self
返回后,B
用于再次使super
的{{1}}可用于alias_method
的实例。
我们需要使用Module#remove_method而不是Module#undef_method。如果使用后者,B
的{{1}}会在发现method_a
没有该方法后放弃寻找B
。
如果您愿意,可以更改两行以使用关键字A
而不是method_a
:
method_b
答案 4 :(得分:0)
没有相当于C ++的A::method_a
但你可以这样做
class A
def method_a
A.instance_method(:method_b).bind(self).call
end
def method_b
puts "Comes from A"
end
end
class B < A
def method_a
super
end
def method_b
puts "Comes from B"
end
end
method_a
中发生的事情是,我们正在检索A method_b
的实施并直接调用它。
虽然
首先使用继承,但这确实有点飞