Как избежать предупреждения "неполной реализации" в частичном базовом классе
Я создал протокол, который мои классы должны реализовать, а затем учесть некоторые общие функции в базовый класс, поэтому я сделал это:
@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> .
Код работает (до тех пор, пока Base не используется напрямую), но компилятор задыхается в конце реализации Base с предупреждением:
Incomplete implementation of class Base
Есть ли способ избежать этого предупреждения или, что еще лучше, более правильный способ получить это частично реализованное поведение абстрактного базового класса в Objc?
Ответы
Ответ 1
Вы могли бы сделать что-то вроде этого:
@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
.
Ответ 2
В определении протокола вам необходимо объявить свои методы под ключевым словом @optional
.
Ваш код должен выглядеть так:
@protocol MyProtocol
@optional
- (void) foo;
- (void) bar;
@end
Смотрите question на SO.
Ответ 3
В Obj-C нет понятия абстрактного класса. Таким образом, вы не можете позволить вашему базовому классу быть абстрактным (что означает, что "не" реализует все методы в протоколе). У вас может быть только 2 варианта. Пусть метод в протоколе будет optionol, а затем реализует его самостоятельно в производном классе. Или, заставляйте все классы в иерархии реализовывать его, но позвольте вызывающему абоненту быть осторожным, чтобы не вызывать неправильные методы
Ответ 4
Я делаю что-то вроде этого
@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;