2010-05-18 161 views
14

我已經創建了我的課需要實現一個協議,然後分解出一些常見的功能集成到一個基類部分基類「完全執行」警告,所以我這樣做:如何避免

@protocol MyProtocol 
- (void) foo; 
- (void) bar; 
@end 

@interface Base <MyProtocol> 
@end 

@interface Derived_1 : Base 
@end 

@interface Derived_2 : Base 
@end 

@implementation Base 
- (void) foo{ 
//something foo 
} 
@end 

@implementation Derived_1 
- (void) bar{ 
//something bar 1 
} 
@end 

@implementation Derived_2 
- (void) bar{ 
//something bar 2 
} 
@end 

在我的代碼中以這種方式使用通用編號<MyProtocol>。

代碼工作(只要基本不能直接使用),但編譯器扼流圈在基地實施的最後一個警告:

Incomplete implementation of class Base

是否有辦法避免這種警告,或甚至更好,在Objc中獲得這種部分實現的抽象基類行爲的更正確方法?

回答

12

你可以想見,做這樣的事情:

@implementation Base 

- (void)bar 
{ 
    if ([self class] == [Base class]) { 
     [self doesNotRecognizeSelector:_cmd]; 
    } 
} 

@end 

這樣的話,你有一個實現,但默認情況下會引發異常。但是,如果派生類無意中調用[super bar]或不覆蓋bar,則會引發異常。如果這不是你想要的,你可以只縮短到:

@implementation Base 

- (void)bar 
{ 
    [self doesNotRecognizeSelector:_cmd]; 
} 

@end 

在這種情況下,一個將引發異常,即使一個子類調用[super bar]或不覆蓋bar

+0

好吧,這將至少強制執行大多數派生類中的實現。 雖然編譯時間警告對於未實現的方法會很好,但是我想沒有辦法(?) 有沒有一種正確的方法可以在Obj-c中完成這個基類的部分實現? – garph0 2010-05-18 10:41:20

+0

不是。正如其他人所指出的,Objective-C沒有抽象基類。我用過的每種方法都只能讓你分開。 – mipadi 2010-05-18 12:03:36

9

在您的協議定義中,您需要在@optional關鍵字下聲明您的方法。

您的代碼應該是這樣的:

@protocol MyProtocol 

@optional 
- (void) foo; 
- (void) bar; 

@end 

看到這個question上左右。

+0

不會@optional使該方法的實現也可選在派生類? 我想要最派生類被迫實現未在基類中實現的方法(在本例中爲「bar」)。 – garph0 2010-05-18 04:21:59

+0

@ garph0,你不能在Obj-C中選擇。 – 2010-05-18 04:32:27

1

在Obj-C中,沒有抽象類的概念。所以,你不能讓你的基類是抽象的(這意味着不''實現協議中的所有方法)。你只能有2個選擇。讓protocol中的方法成爲optionol,然後在派生類中自己實現它。或者,強制所有的類層次結構中實現它,而是告訴對方要小心,不要調用不正確的方法的人

0

我做這樣的事情

@protocol MyProtocol 
- (void) foo; 
- (void) bar; 
@end 

@interface BaseAbstract 
- (void) bar; // give a default implementation 
@end 

@interface Derived_1 : BaseAbstract<MyProtocol> 
// you will get a compiler warning for foo() since it is not implemented 

// you will NOT get compiler for bar() warning since a default 
// implementation is inherited 
@end 

@interface Derived_2 : BaseAbstract<MyProtocol> 
@end 

typedef BaseAbstract<MyProtocol> Base;