我有两个课程A
和B
。类B
会覆盖类foo
的{{1}}方法。类A
有一个B
方法,我想调用超类的bar
方法。这种呼叫的语法是什么?
foo
对于类方法,我可以通过显式地为类名添加前缀来调用继承链中的方法。我想知道是否存在类似习惯的方法。
class A
def foo
"hello"
end
end
class B < A
def foo
super + " world"
end
def bar
# how to call the `foo` method of the super class?
# something similar to
super.foo
end
end
修改
我的用例很通用。对于特定情况,我知道我可以使用class P
def self.x
"x"
end
end
class Q < P
def self.x
super + " x"
end
def self.y
P.x
end
end
技术。这是Java或C ++中的常见功能,所以我很想知道是否可以在不添加额外代码的情况下执行此操作。
答案 0 :(得分:29)
在Ruby 2.2中,您现在可以使用Method#super_method
例如:
class B < A
def foo
super + " world"
end
def bar
method(:foo).super_method.call
end
end
参考:https://bugs.ruby-lang.org/issues/9781#change-48164和https://www.ruby-forum.com/topic/5356938
答案 1 :(得分:23)
你可以这样做:
def bar
self.class.superclass.instance_method(:foo).bind(self).call
end
答案 2 :(得分:13)
在这种特殊情况下,您可以在alias :bar :foo
def foo
之前class B
将foo
重命名为bar
,但当然可以为别名你喜欢的任何名字,并从中称呼它。 This question有一些替代方法可以在继承树中进一步完成。
答案 3 :(得分:5)
在重新定义之前,您可以alias old_foo foo
以旧名称保留旧实现。 (从技术上讲,可以采用超类的实现并将其绑定到子类的实例,但它很笨拙,并非完全没有惯用,并且在大多数实现中可能都很慢。)
答案 4 :(得分:0)
基于@Sony的答案。
如果你想在某些method
上调用my_object
方法并且它已经覆盖了几个更高的类(比如Net::HTTPRequest#method
),而不是.superclass.superclass.superclass
使用:
Object.instance_method(:method).bind(my_object)
像这样:
p Object.instance_method(:method).bind(request).call(:basic_auth).source_location