2010-05-18 155 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;