Ruby:在子类中调用父类的重写方法

时间:2011-12-23 13:03:56

标签: ruby

假设我有从A类派生的B类

是否可以像这样调用A的覆盖方法?

class A
  def method1
  end
  def method2
  end
end

class B < A
  def method1
  ### invoke method2 of class A is what I want to do here
  end
  def method2
  end
end

#并不完全与How do I call an overridden parent class method from a child class?重复,但我们似乎也希望做同样的事情。

3 个答案:

答案 0 :(得分:16)

我在这里假设B应该从A继承而你只是在你的示例代码中输入了一个拼写错误。如果不是这种情况,就没有办法做你想做的事。

否则,您可以通过将A的{​​{1}}实例方法绑定到当前的method2对象并使用以下方法调用它来使用反射执行您想要的操作:

B

请注意,除非你真的需要,否则你不应该拔出像这样的大黑魔法枪。在大多数情况下,重新设计类层次结构以便您不需要这样做是更好的选择。

答案 1 :(得分:9)

您可以使用alias语句为父方法创建同义词,并从overriden方法中调用它:

class A
  def method1
    puts '1'
  end
  def method2
    puts '2'
  end
end

class B < A
  alias parent_method1 method1
  alias parent_method2 method2
  def method1
    parent_method2
  end
  def method2
  end
end

b = B.new
b.method1 # => 2

答案 2 :(得分:5)

@ sepp2k的答案在技术上是正确的,但是我想解释一下为什么这种技术在我看来不合适(所以问题在技术上很有意思,但导致了错误的目标):

  • Ruby不允许在B实例中调用super.method2的上下文中调用method1,因为这样做是错误的。当您的实例是超类的特化时,应该使用类继承。这包括你通常只通过调用super来扩展行为,并在该调用之前或之后另外做一些事情。
  • 有一些像Java和其他语言的语言允许为另一种方法调用super,这导致类似于意大利面条代码的东西,但是面向对象的方式。没有人知道何时调用哪种方法,所以尽量避免使用它。

因此,请尝试找出您要更改呼叫的原因,然后解决此问题。如果A中的method1在B中实现错误,则不应该是子类。