Можно ли унаследовать протоколы и категории Objective-C?
Я немного смущен некоторыми концепциями вокруг протоколов и категорий Objective-C.
могут ли протоколы и категории наследоваться подклассами в Objective-C?
5 ответов
категории-это коллекции методов, которые добавляются в класс во время выполнения. Поскольку Objective-C использует динамическую привязку, это означает, что методы, определенные в категории, доступны классу и всем его подклассам. В частности, селекторы привязаны к методам в точке их вызова, а не во время компиляции или при первой загрузке программы. Категории добавляются в классы, когда они (категории) загружаются.
протоколы определяют коллекции сигнатуры методов, которые обещают реализовать соответствующие им классы. Как только класс объявил, что он соответствует протоколу, его, как если бы методы были объявлены в интерфейсе этого класса, и правила наследования точно такие же: подклассы наследуют объявление и реализацию методов протокола, но также могут переопределить реализацию суперкласса.
сами протоколы можно расширить для произведения новых протоколов. состоящая из надмножества методы в исходном протоколе. Фактически, так же, как большинство классов наследуют от NSObject
класс, большинство протоколов продлить NSObject
протокол (протокол фамилии и имена классов в разных пространствах имен). Это так, что объекты объявлены как id<WhateverProtocol>
могут быть отправлены основные сообщения типа -retain
, -release
и так далее без генерации предупреждений компилятора.
категории подобны расширению класса. Вы можете добавить свои собственные методы в другие классы (например, NSString или что-нибудь еще). Это означает, что любой подкласс также получает методы.
тогда как протокол-это список методов, который требует, чтобы класс, который подтверждает ему, реализовал все это (если он не использует тег @optional). Таким образом, нет смысла в его подклассе наследовать его.
Edit:
для протокола я понял, что недостаточно ясно выразился. Методы протокола, которые были реализованы в его суперклассе can быть унаследованным, однако, я имел в виду, что обычно вам не нужно переопределять метод протокола вашего суперкласса.
Ваш вопрос неясен. Вы можете спросить, наследуют ли подклассы протоколы и категории своего суперкласса. @theAmateurProgrammer ответил на это.
вы также можете спросить, могут ли категории и протоколы сами наследовать от других категорий и протоколов. Для категорий ответ-нет. Для протоколов ответ "да", и на самом деле протоколы почти всегда должны наследовать такие же классы, как эти:
@protocol SomeProtocol <NSObject>
...
@end
здесь говорится, что все, что соответствует <SomeProtocol>
также соответствует <NSObject>
(который является протоколом, а также класс). Это позволяет вызывать такие методы, как respondsToSelector:
, что очень важно для большинства реализаций протокола.
протоколы интерфейсы в Java. Так, класс предоставляет протокол для доступа к нему.
вы можете "подкласс" протоколы так же, как в Java вы можете "подкласс" интерфейсы.
категории, с другой стороны, это способ добавить больше методов в класс. Ограничение заключается в том, что вы не можете добавлять переменные экземпляра с категорией. Вы можете получить доступ только к существующим переменным экземпляра.
Это очень полезно, потому что это позволяет избежать создания большой хрупкой иерархия подклассов.
Итак, суть в том, что если вы хотите, чтобы представление разных классов соответствовало стандартному интерфейсу, используйте протокол. Если вы хотите добавить несколько методов к существующему классу без разделения на подклассы, перейдите на категории.
однако следует иметь в виду, что, когда вы добавляете методы в категорию - о чем мне напомнили коллеги по работе, - вы делаете эти методы доступными повсюду. Я читал в нескольких местах, что распространенная ошибка новичков-сходить с ума по категориям, используя их все время вместо создания новых классов, которые выполняли бы эту работу.
Итак, если новый метод категории, который вы рассматриваете, действительно специфичен или, скорее, тесно связан с бизнес - функцией, то, вероятно, это не должна быть категория. Они действительно должны использоваться только для общих дополнений к базовому классу.
NSObject соответствует протоколу NSObject
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
скажем, у нас есть подкласс NSObject
@interface FTGAnimal : NSObject
@end
@implementation FTGAnimal
@end
мы видим, что FTGAnimal фактически соответствует протоколу NSObject
if ([FTGAnimal conformsToProtocol:@protocol(NSObject)]) {
NSLog(@"FTGAnimal conforms to NSObject protocol");
}