I have created a protocol that my classes need to implement, and then factored out some common functionality into a base class, so I did this:
我创建了一个我的类需要实现的协议,然后将一些常用功能分解到基类中,所以我这样做了:
@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
In this way in my code I use a generic id<MyProtocol>.
这样在我的代码中我使用通用id
The code works (as long as Base is not used directly) but the compiler chokes at the end of the implementation of Base with a warning:
代码可以工作(只要不直接使用Base),但编译器在Base的实现结束时会发出警告:
Incomplete implementation of class Base
Is there a way to avoid this warning or, even better, a more proper way to obtain this partially implemented abstract base class behavior in Objc?
有没有办法避免这种警告,或者更好的是,在Objc中获得这种部分实现的抽象基类行为的更合适的方法?
4 个解决方案
#1
12
You could conceivably do something like this:
你可以想象做这样的事情:
@implementation Base
- (void)bar
{
if ([self class] == [Base class]) {
[self doesNotRecognizeSelector:_cmd];
}
}
@end
That way, you have an implementation, but by default it raises an exception. However, if a derived class accidentally calls [super bar]
or does not override bar
, then the exception won't be raised. If that's not what you want, you could just shorten it to:
这样,您就有了一个实现,但默认情况下会引发异常。但是,如果派生类意外调用[super bar]或不覆盖bar,则不会引发异常。如果那不是你想要的,你可以缩短它:
@implementation Base
- (void)bar
{
[self doesNotRecognizeSelector:_cmd];
}
@end
In which case, an exception will be raised, even if a subclass calls [super bar]
or does not override bar
.
在这种情况下,即使子类调用[super bar]或不覆盖bar,也会引发异常。
#2
9
In your protocol definition, you need to declare your methods under the @optional
keyword.
在协议定义中,您需要在@optional关键字下声明方法。
Your code should look like this:
您的代码应如下所示:
@protocol MyProtocol
@optional
- (void) foo;
- (void) bar;
@end
See this question on SO.
在SO上看到这个问题。
#3
1
In Obj-C, there is no concept of abstract class. So that, you can not let your Base class to be abstract (which means dont' implements all methods in the protocol). You can only have 2 choices. Let the method in protocol to be optionol and then implements it yourself in the derived class. Or, force all classes in the hierarchy to implement it, but let the caller to be careful not call the incorrect method ones
在Obj-C中,没有抽象类的概念。所以,你不能让你的Base类是抽象的(这意味着不要'实现协议中的所有方法)。你只能有2个选择。让protocol中的方法为optionol,然后在派生类中自己实现它。或者,强制层次结构中的所有类来实现它,但是让调用者注意不要调用不正确的方法
#4
0
I do something like this
我这样做
@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;
#1
12
You could conceivably do something like this:
你可以想象做这样的事情:
@implementation Base
- (void)bar
{
if ([self class] == [Base class]) {
[self doesNotRecognizeSelector:_cmd];
}
}
@end
That way, you have an implementation, but by default it raises an exception. However, if a derived class accidentally calls [super bar]
or does not override bar
, then the exception won't be raised. If that's not what you want, you could just shorten it to:
这样,您就有了一个实现,但默认情况下会引发异常。但是,如果派生类意外调用[super bar]或不覆盖bar,则不会引发异常。如果那不是你想要的,你可以缩短它:
@implementation Base
- (void)bar
{
[self doesNotRecognizeSelector:_cmd];
}
@end
In which case, an exception will be raised, even if a subclass calls [super bar]
or does not override bar
.
在这种情况下,即使子类调用[super bar]或不覆盖bar,也会引发异常。
#2
9
In your protocol definition, you need to declare your methods under the @optional
keyword.
在协议定义中,您需要在@optional关键字下声明方法。
Your code should look like this:
您的代码应如下所示:
@protocol MyProtocol
@optional
- (void) foo;
- (void) bar;
@end
See this question on SO.
在SO上看到这个问题。
#3
1
In Obj-C, there is no concept of abstract class. So that, you can not let your Base class to be abstract (which means dont' implements all methods in the protocol). You can only have 2 choices. Let the method in protocol to be optionol and then implements it yourself in the derived class. Or, force all classes in the hierarchy to implement it, but let the caller to be careful not call the incorrect method ones
在Obj-C中,没有抽象类的概念。所以,你不能让你的Base类是抽象的(这意味着不要'实现协议中的所有方法)。你只能有2个选择。让protocol中的方法为optionol,然后在派生类中自己实现它。或者,强制层次结构中的所有类来实现它,但是让调用者注意不要调用不正确的方法
#4
0
I do something like this
我这样做
@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;