我如何调用超类方法

Har*_*tty 30 ruby

我有两节课A,和B.类B重写了类的foo方法A.Class 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
Run Code Online (Sandbox Code Playgroud)

对于类方法,我可以通过显式地为类名添加前缀来在继承链上调用方法.我想知道是否有类似的习惯用法.

class P
 def self.x
   "x"
 end
end

class Q < P
 def self.x
   super + " x"
 end

 def self.y
   P.x
 end
end
Run Code Online (Sandbox Code Playgroud)

编辑 我的用例是一般的.对于特定情况,我知道我可以使用alias技术.这是Java或C++中的常见功能,所以我很想知道是否可以在不添加额外代码的情况下执行此操作.

小智 33

在Ruby 2.2中,您Method#super_method现在可以使用

例如:

class B < A
  def foo
    super + " world"
  end

  def bar
    method(:foo).super_method.call
  end
end
Run Code Online (Sandbox Code Playgroud)

参考:https://bugs.ruby-lang.org/issues/9781#change-48164https://www.ruby-forum.com/topic/5356938


Son*_*tos 23

你可以做:

 def bar
   self.class.superclass.instance_method(:foo).bind(self).call
 end
Run Code Online (Sandbox Code Playgroud)

  • 这不是在Ruby中调用重写方法的最佳方法,请说不是这样.编辑:是的,问题中的评论链接到更好的选项. (22认同)
  • @ Vinnyq12是的,当您知道要从超类调用的方法时,`alias`对于特定情况更好; 但是这里的OP要求一般情况,而不必别名超类的每个方法. (3认同)

Ark*_*kku 13

在这种特殊情况下,你可以只是alias :bar :foo之前def fooclass B重命名旧的foobar,但当然,你可以别名任何名称,你喜欢和来自调用它.这个问题有一些替代方法可以在继承树中进一步完成.


Chu*_*uck 5

您可以alias old_foo foo在重新定义之前将旧实现保留在新名称下.(从技术上讲,有可能采用超类的实现并将其绑定到子类的实例,但它很笨拙,并非完全没有惯用,并且在大多数实现中可能都很慢.)