Реализовать чисто виртуальный метод в Objective-C - PullRequest
41 голосов
/ 07 марта 2011

Я хочу пойти туда. Если серьезно, то как можно реализовать чисто виртуальный метод «Apple»? Используете ли вы протокол с базовым классом и генерируете исключения для этих методов?

Ответы [ 6 ]

55 голосов
/ 07 марта 2011

Когда вы программируете в Objective-C, вам нужно очистить свой ум от таких вещей, как виртуальные методы.Вы не вызываете методы для объектов Objective-C, вы отправляете им сообщения.Объекты либо отвечают на сообщения, либо нет, но из-за динамического связывания вы не можете сказать это до времени выполнения.

Таким образом, вы можете объявить метод для базового объекта и не предоставлятьреализация, нет проблем (за исключением предупреждения компилятора), но вы не можете иметь флаг компилятора, когда вы непосредственно создаете экземпляр объекта с такими методами, и он не выдаст ошибку во время выполнения, если вы фактически не отправите это сообщение объекту.

Лучший способ создать "виртуальные" базовые классы (на мой взгляд) - объявить метод и дать ему реализацию-заглушку, которая выдает подходящее исключение.

32 голосов
/ 07 марта 2011

В Objective-C нет чистой виртуальной поддержки, как в C ++.

Имитацией будет то, что вы объявляете метод в своем интерфейсе, но не реализуете его в своем файле .m. Конечно, вы получите предупреждения компилятора, но IIRC вы можете отключить их. Но вы не получите предупреждений / ошибок, если не перезапишите их в подклассе, который вы получаете в C ++ (IIRC).

Альтернативой может быть реализация их с помощью тела NSAssert(NO, @"Subclasses need to overwrite this method");. Тем не менее, вы могли бы поймать это только во время выполнения, а не во время компиляции.

7 голосов
/ 07 марта 2011

В зависимости от того, что вы делаете, шаблон делегата может быть более подходящим, чем подкласс, где делегат определен как id<YourDelegateProtocol>.Компилятор сгенерирует предупреждение, если требуемые методы в протоколе делегата не реализованы.

В Objective-C обычно избегают подклассов, поскольку объекты не могут наследоваться от нескольких суперклассов, но они могут реализовывать несколько протоколов.

6 голосов
/ 21 января 2013

Вы должны использовать:

- (void)doesNotRecognizeSelector:(SEL)aSelector method. 

Как отмечает Apple, здесь: https://developer.apple.com/library/mac/#documentation/cocoa/reference/Foundation/Classes/NSObject_Class/Reference/Reference.html

2 голосов
/ 07 марта 2011

У вас есть несколько вариантов, но вы на правильном пути.

ObjC не поддерживает это напрямую, поэтому подклассы для реализации протокола - лучший способ проверить его при компиляции.

«Тайная» реализация метода в базовом классе и утверждение - это то, что я делаю, чтобы подтвердить, что подкласс правильно распределен по подклассам во время выполнения.Некоторые люди испытывают смешанные чувства по поводу утверждений или должны оставить их активными, так что это не всегда хорошее решение.

Вы также можете заставить подклассы использовать определенный конструктор класса и последовательность инициализации, а затем проверить, что они реализовали все необходимое, прежде чемвозвращая экземпляр, в случае, если предупреждения компилятора не обрезают его.

Но в ObjC отсутствуют некоторые функции языка, которые позволяют клиентам выстрелить себе в ногу, или обойти то, что они хотят, так что ... вы не должнызацикливайтесь на его принудительном выполнении.

примечание: исключения являются очень редкими (и немного небезопасными) в ObjC.

0 голосов
/ 12 апреля 2013

Виртуальный метод - это метод, поведение которого может быть переопределено в наследующем классе функцией с такой же сигнатурой (то есть с тем же именем с тем же числом параметров и типом параметров).

Пример: -

@implementation BaseClass

-(void)viewDidLoad
{
 [self virtualMethod:123];
}

-(void)virtualMethod:(int)param
{
 //implement this method in subclass
}

@end

/////////////////////////////////////////////// /////

@interface ChildClass:BaseClass
@end

@implementation ChildClass

-(void)virtualMethod:(int)param
{
 NSLog(@"There is no keyword "Virtual" in Objective C.");
}
@end

Выход: -

"В Objective C нет ключевого слова" Virtual "."

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...