简体   繁体   English

我如何调用超类方法

[英]How do I call a super class method

I have two classes A , and B . 我有两个A类和B类。 Class B overrides the foo method of class A . B类重写A类的foo方法。 Class B has a bar method where I want to call the foo method of the super class. B类有一个bar方法,我想调用超类的foo方法。 What is the syntax for such a call? 这种电话的语法是什么?

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

For class methods I can call the methods up the inheritance chain by explicitly prefixing the class name. 对于类方法,我可以通过显式地为类名添加前缀来在继承链上调用方法。 I wonder if there is a similar idiom for instance methods. 我想知道是否有类似的习惯用例。

class P
 def self.x
   "x"
 end
end

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

 def self.y
   P.x
 end
end

Edit My use case is general. 编辑我的用例是一般的。 For a specific case I know I can use alias technique. 对于特定情况,我知道我可以使用alias技术。 This is a common feature in Java or C++, so I am curious to know if it is possible to do this without adding extra code. 这是Java或C ++中的常见功能,所以我很想知道是否可以在不添加额外代码的情况下执行此操作。

In Ruby 2.2, you can use Method#super_method now 在Ruby 2.2中,您现在可以使用Method#super_method

For example: 例如:

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

  def bar
    method(:foo).super_method.call
  end
end

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

You can do: 你可以做:

 def bar
   self.class.superclass.instance_method(:foo).bind(self).call
 end

In this particular case you can just alias :bar :foo before def foo in class B to rename the old foo to bar , but of course you can alias to any name you like and call it from that. 在这种特殊情况下,您可以使用alias :bar :fooclass B def foo alias :bar :foo之前将旧foo重命名为bar ,但当然您可以使用任何名称的别名并从中调用它。 This question has some alternative ways to do it further down the inheritance tree. 这个问题有一些替代方法可以在继承树中进一步完成。

You can alias old_foo foo before redefining it to keep the old implementation around under a new name. 您可以在重新定义alias old_foo foo之前使用alias old_foo foo ,以便在旧名称下保留旧实现。 (Technically it is possible to take a superclass's implementation and bind it to an instance of a subclass, but it's hacky, not at all idiomatic and probably pretty slow in most implementation to boot.) (从技术上讲,可以采用超类的实现并将其绑定到子类的实例,但它很笨拙,并非完全没有惯用,并且在大多数实现中可能都很慢。)

Based on @Sony's answer. 基于@Sony的回答。

In case when you want to call the method method on some my_object and it's already overriden somewhere several classes higher (like for the Net::HTTPRequest#method ), instead of doing .superclass.superclass.superclass use the: 如果你想在某些my_object上调用method方法并且它已经覆盖了几个更高的类(比如Net::HTTPRequest#method ),而不是做.superclass.superclass.superclass使用:

Object.instance_method(:method).bind(my_object)

Like this: 像这样:

p Object.instance_method(:method).bind(request).call(:basic_auth).source_location

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM