2011-12-23 157 views
9

假設我擁有從A類派生的類BRuby:調用子類中的父類的重寫方法

是否可以像這樣調用A的overrided方法?

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

您的意思是說您的示例代碼中B是A的子類? – sepp2k 2011-12-23 13:07:11

+1

如果b是一個子類,那麼你可以簡單地在你的b中調用super。 – three 2011-12-23 13:10:09

+1

不,他需要從後代的方法1調用super的method2。在Ruby中沒有辦法(我知道)要做到這一點。 – 2011-12-23 13:21:06

回答

16

我在這裏假設B應該從A繼承,而您只是在您的示例代碼中犯了一個錯字。如果情況並非如此,就沒有辦法做你想做的事情。

否則,你可以做你想做使用反射通過的Amethod2實例方法結合到當前的B對象並調用它像這樣的內容:

class A 
    def method1 
    end 
    def method2 
    end 
end 

class B < A 
    def method1 
    A.instance_method(:method2).bind(self).call 
    end 
    def method2 
    end 
end 

不過請注意,你不應該拉出大除非你真的需要這樣的黑魔槍。在大多數情況下,重新設計您的類層次結構以便您不需要這樣做是更好的選擇。

+0

謝謝。另一個魔術把我的袖子:-) – 2011-12-23 14:36:29

+0

+1我會張貼相同的東西。我也認爲這很少,如果有的話,需要使用。爲什麼重寫A#method2如果你仍然需要它在B?我只在嘗試排除方法行爲故障時使用綁定技巧,例如在irb。 – Kelvin 2011-12-26 21:47:29

9

可以使用alias語句創建一個父類的方法的代名詞,從覆蓋方法調用它:

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 
5

@ sepp2k的答案是技術上是正確的,但是我想解釋一下爲什麼這個技術不是適當的在我看來,(所以這個問題在技術上是有趣的,但導致了錯誤的目標):

  • 紅寶石不允許調用super.method2method1稱爲B的一個實例的背景下,becau這是做錯了。當你的實例是超類的特化時,應該使用類繼承。這包括你通常只會擴展行爲,通過調用super並在該調用之前或之後額外執行某些操作。
  • 有像Java和其他語言,允許調用超另一種方法,這導致類似於意大利麪條代碼,但面向對象的方式。沒有人知道何時調用哪些方法,所以儘量避免它。

所以試着找出你想改變呼叫的原因並解決。如果你在A中的你的method1在B中實現了錯誤,那麼你不應該子類化。

+0

「即使在思考@ sepp2k的答案是否正確時」是否有任何理由認爲它不是? – sepp2k 2011-12-23 13:46:16

+0

對不起,我想表達你的答案在技術上是正確的,但這個問題本身就有缺陷。我會糾正它,對於那個誤解抱歉。 – mliebelt 2011-12-23 14:06:51