2011-08-10 50 views
12

如果一個方法是在兩個一類和該類的類定義的,它是未定義的,其執行將被調用。目標C類和繼承

但這是如何與繼承交互?具體來說:

  • 給定子類中的超類別方法和常規方法,是否保證在子類的成員上調用子類實現會獲勝?
  • 給定一個超常規的方法和子類中的方法試圖將其覆蓋,能夠保證所有的子類中的一員對調用的時候,子類實現贏?
  • 給定一個超類中的方法和子類分類方法,能夠保證所有的子類中的成員在調用的時候,子類中的方法將勝出?
+0

我不會說 '沒辦法'。您可以在類別+加載方法中攔截原始實現並獲得一些樂趣;) –

+3

如果某個類別覆蓋該類別中存在的方法,則將調用該類別方法。當同一類中的兩個類別實現/覆蓋相同的方法時,會出現衝突。這很重要,因爲很多Cocoa類的方法都是在類別中實現的。如果你試圖覆蓋一個框架定義的方法,它可能已經在一個類中實現,而哪個實現優先是* undefined *。 – albertamg

回答

49

就讓我們把這種方式。不要用類別,句點,回答結束來覆蓋方法。

+2

太糟糕了,我今天沒有投票贊成這個。 –

+0

我認爲人們喜歡理性,而不是盲目的建議 – onmyway133

+0

@entropy:在問這個問題數百次後,Joshuas的答案完全符合需要。類別不是繼承和子類化的工具。 – vikingosegundo

40

如果在該類的類和類別中都定義了一個方法,則 未定義將調用哪個實現。

這是不正確;類別方法將永遠贏。什麼都不行,雖然是如果你有實現相同的方法多個類別,那麼「哪一個贏」是不確定的。

它通常是「最後加載勝」,但真的不是一個硬性的規則,無論是。

注意,因爲很多類會在內部有跨類別的執行劃分爲代碼組織的目的,你可以不依賴於第一條規則反正。

總之,約書亞說。 請勿使用類別覆蓋方法。

除了繼承的原因,你也惡毒破壞了封裝,當你這樣做。這不是基於類別的實現覆蓋現有的方法,而是完全取代它。因此,如果你不重現每一個最後的內部實現細節,包括錯誤,換貨不會很工作的權利和調試這將是

+1

那麼,這是我的問題的一部分。超類(UIView)是一個Apple類。我有一個類添加了一個方法;我們稱之爲myUIViewCategoryMethod。如果我在子類中重寫該方法,我可以確定子類版本會贏嗎?如果我在一個子類上使用類別,該怎麼辦? –

+2

是的 - 子類實現將永遠勝利。 – bbum

+0

子類化並不總是可用的,但有時需要替換或增強某個功能。在這種情況下,絕對不推薦分類覆蓋。相反,使用Objective C Runtime與您想修改的方法交換您自己的方法的實現,並在適當情況下調用原始實現。 –

-1

從我測試

  1. 給定一個超類中的方法,並在 子類常規方法中,它保證了子類實現將贏得 子類的成員在調用時? =>子勝
  2. 給定一個超常規的方法和子類中的方法 試圖覆蓋它,是保證子類中的一員叫上當子 類別執行會勝出? => 子類類勝
  3. 給定一個超類方法和子類類中的方法,是 它保證當 子類的成員上被稱爲子類類方法將贏了嗎?=>子類別勝

看看在Test category and subclass

+0

談到類別重寫的子類似乎是錯誤的,我已經。對於這個話題,他可能是堆棧溢出最有能力的人之一。 – vikingosegundo

+0

@vikingosegundo你是對的。我只是想通過一個小測試來澄清這一點。運行時添加類別方法的順序必須與bbum所說的一樣: – onmyway133

+0

許多類按類別分類。我們不知道他們加載的順序。 – vikingosegundo