2013-12-07 53 views
1

我一直在努力尋找一個正確和明確的答案,所以我決定在這裏提問。如何禁止繼承init方法?

創建類A和定義init方法有:

@interface A : NSObject 

- (id)initWithHealth:(int)hp; 

@end 

然後我創建類B,即從類A繼承和定義另一個init方法有:

@interface B : A 

- (id)initWithHealth:(int)hp andDamage:(int)dmg; 

@end 

在主,當我要從類B實例化一個對象時,Xcode會建議我使用- (id)initWithHealth:(int)hp;- (id)initWithHealth:(int)hp andDamage:(int)dmg; init方法。 如何禁止B類繼承A類的init方法?我希望我的類B只有一個我定義的init方法。有沒有辦法做到這一點?

在此先感謝。

+2

不,但您可以在B類中禁用A的方法:http://stackoverflow.com/a/5772821/412916 – Jano

回答

0

編輯(感謝Sulthan和rmaddy)

OK我已經找到了答案,我的問題,我應該使用類別。 但是,感謝所有參與的人。

+0

它不是一個關鍵字。 – Sulthan

+0

'@ categories'是什麼? Objective-C中沒有這樣的語法。 – rmaddy

+0

是的,對不起,我的意思是使用類別,如 @interface Blah(Category) – Soberman

3

您有幾種選擇:

選項1 - 提供一個默認的「損害」與老init方法。在B類你可以這樣:

- (id)initWithHealth:(int)hp { 
    return [self initWithHealth:hp andDamage:0]; // use an appropriate default 
} 

- (id)initWithHealth:(int)hp andDamage:(int)dmg { 
    self = [super initWithHealth:hp]; 
    if (self) { 
     // do stuff with dmg 


    return self; 
} 

選擇2 - 導致運行時錯誤,如果使用舊init方法。在B類你可以這樣:

- (id)initWithHealth:(int)hp { 
    NSAssert(0, @"Dont use this"); 

    return nil; // make compiler happy 
} 

我個人認爲選擇1是更好的選擇。

+0

+1正確答案IMO,在超類中調用指定的初始化器並覆蓋子類中的超類指定器根據蘋果的規定。我不會在選項2中使用NSASssert,我會明確地拋出異常。 – JeremyP

0

在您的子類B中,您可以明確定義該方法,以使該類在運行時不會對其作出響應。

- (instancetype) initWithHealth:(int) hp { 
    [self release]; 
    [super doesNotRecognizeSelector:_cmd]; 
    return nil; 
} 

這是非常傳統的,我已經看到它用於很多開源項目和我的客戶的一些項目。我認爲這比@ rmaddy的解決方案更可取,因爲您希望確保從不調用繼承的方法。如果你想在調用繼承的init方法時使用一個合理的默認值,那麼其他代碼就可以正常工作。