2012-07-07 70 views
3

似乎有它是否能夠在Objective-C「過載」的方法的一些爭論/不一致。拋開Objective-C中定義方法重載是不可能的,因爲術語與C++相同(因爲方法簽名語法的差異),所以我會特別問:下列哪項是允許的,哪些不是?Objective-C的方法覆蓋/重載混亂

1)的一類聲明/實施這兩種方法:

- (void) doSomethingWithObject:(ClassA*) object; 
- (void) doSomethingWithObject:(ClassB*) object; 

2)一類聲明/實施這兩種方法:

- (void) doSomethingWithObject:(ClassA*) object; 
- (BOOL) doSomethingWithObject:(ClassA*) object; 

3)一類聲明/實現該方法:

- (void) doSomethingWithObject:(ClassB*) object; 

...當其超類聲明/實現此方法時:

- (void) doSomethingWithObject:(ClassA*) object; 

(和衝突的返回值的類似物),兩者都在A)ClassBClassA,和B)不下降。

回答

7

問題1:沒有做不到的:Objective-C中不包括方法名的類型;沒有搗亂。它可能與Objective-C++一起工作 - 從來沒有使用過它。

問題2:相同。將無法工作。

問題3:將工作。

編輯:在一般情況下,方法名不包括任何類型的,所以,如果你帶的類型和他們是一樣的,然後它會被認爲是相同的,因此不會在同一個類被允許。沿着同樣的路線,如果它在不同的類中,它將工作,但如果調用中使用的類型和被調用的類型不完全一致,可能會產生一些混淆。

+0

OK,所以基本上,對於同一個類中的每個方法,字符串(例如)「methodWithParam1:param2:param3:」('選擇器')必須是唯一的,並且在子分類(覆蓋)時更改參數類型/好嗎? – 2012-07-07 11:09:09

+1

情況3很可能會生成編譯器警告。超類的方法需要'ClassA'的一個實例。這意味着該類的所有對象*及其子類*都必須接受同一方法的任何'ClassA'對象。這是必要的,因爲子類的實例可以在超類的實例可以使用的任何地方使用。但是你試圖用更狹窄的要求重新聲明方法 - 它只接受'ClassB'的對象。這是正確的,在運行時,該方法將被調用,但它是否會工作,因爲它傳遞的是另一個問題。 – 2012-07-07 14:24:37

+0

我想知道UITableView的委託屬性會發生什麼情況。它應該覆蓋UIScrollView的委託屬性,但它進一步限制它只接受也符合UITableViewDelegate協議的對象。我不知道內部,但我相信你不能'推翻'ivars。我假設UITableView中的-setDelegate:propert訪問器在傳遞的參數(參數)中施加了額外的限制。 – 2012-07-08 13:26:38

1

你想在C++方面編譯器在不搞清楚調用根據輸入的類型的實例方法的靜態綁定。

的Objective-C不工作的方式。相反,所有綁定在運行時都是動態的。有點像在C++中聲明爲「虛擬」的所有方法。程序員負責傳遞適當的變量,以您的方法期望的方式響應。

你的方法可根據該查詢在是否應對某一特定選擇所傳遞的對象,並採取適當的行動,如果你想更強大的性能。或者你的方法可能會要求傳遞的對象是否是它期望的類型。再次,這將在您的方法在運行時完成。不是由編譯器。

因此,答案是,聲明爲:

- (void) doSomethingWithObject:(id) object; 

...然後傳中任何你喜歡的對象。

+0

呃,不......我絕對沒有用C++來思考。我只是碰巧知道編譯器會做一些類型檢查(當你指定'id'以外的內容時),只是不知道範圍。 – 2012-07-08 07:24:14