我如何调用超类方法

时间:2010-04-02 00:06:41

标签: ruby

我有两个课程AB。类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 ++中的常见功能,所以我很想知道是否可以在不添加额外代码的情况下执行此操作。

5 个答案:

答案 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-48164https://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 Bfoo重命名为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