我创建了一个我的类需要实现的协议,然后将一些常用功能分解到基类中,所以我这样做了:
@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
这样在我的代码中我使用了通用id&lt; MyProtocol&gt;。
代码有效(只要不直接使用Base),但编译器在Base的实现结束时会发出警告:
Incomplete implementation of class Base
有没有办法避免这种警告,或者更好的是,在Objc中获得这种部分实现的抽象基类行为的更合适的方法?
答案 0 :(得分: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
,也会引发异常。
答案 1 :(得分:9)
在协议定义中,您需要在@optional
关键字下声明您的方法。
您的代码应如下所示:
@protocol MyProtocol
@optional
- (void) foo;
- (void) bar;
@end
在SO上查看此question。
答案 2 :(得分:1)
在Obj-C中,没有抽象类的概念。所以,你不能让你的Base类是抽象的(这意味着不要'实现协议中的所有方法)。你只能有2个选择。让protocol中的方法为optionol,然后在派生类中自己实现它。或者,强制层次结构中的所有类来实现它,但让调用者小心不要调用不正确的方法
答案 3 :(得分: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;