Я немного смущен некоторыми понятиями вокруг Objective-C протоколов и категорий.
Могут ли протоколы и категории наследоваться подклассами в Objective-C?
Я немного смущен некоторыми понятиями вокруг Objective-C протоколов и категорий.
Могут ли протоколы и категории наследоваться подклассами в Objective-C?
Категории представляют собой коллекции методов, которые добавляются в класс во время выполнения. Поскольку Objective-C использует динамическое связывание, это означает, что методы, определенные в категории, доступны для класса и всех его подклассов. В частности, селекторы привязаны к методам в точке, где они вызывается, а не во время компиляции или когда программа загружается первой. Категории добавляются в классы, когда они (категории) загружаются.
Протоколы определяют коллекции сигнатур методов, которые обещают реализовать соответствующие им классы. Как только класс объявил, что он соответствует протоколу, он как будто методы объявлены в этом интерфейсе класса, а правила наследования точно такие же: подклассы наследуют декларацию и реализацию методов протокола, но могут также выбирать переопределение суперкласса реализация.
Протоколы могут быть расширены для создания новых протоколов. состоящий из надмножества методов в исходном протоколе. Фактически, так же, как большинство классов наследует класс NSObject
, большинство протоколов расширяют протокол NSObject
(имена протоколов и имена классов находятся в разных пространствах имен). Это значит, что объектам, объявленным как id<WhateverProtocol>
, могут быть отправлены базовые сообщения, такие как -retain
, -release
и т.д., Не генерируя предупреждения компилятора.
Категории похожи на расширение класса. Вы можете добавить свои собственные методы в другие классы (например, NSString или что-то еще). Это означает, что любой подкласс также получает методы.
В то время как протокол представляет собой список методов, которым требуется класс, который подтверждает его, чтобы реализовать все это (если он не использует тег @optional). Таким образом, нет смысла подзадача этого класса.
Edit:
Для реализации протокола я понял, что я недостаточно ясен. Протокольные методы, которые были реализованы в этом суперклассе, могут быть унаследованы, однако, я имел в виду, как правило, вам не нужно переопределять ваш метод протокола суперкласса.
Твой вопрос непонятен. Возможно, вы спрашиваете, наследуют ли подклассы протоколы и категории своего суперкласса. @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
Мы видим, что FTGnimal фактически соответствует протоколу NSObject
if ([FTGAnimal conformsToProtocol:@protocol(NSObject)]) {
NSLog(@"FTGAnimal conforms to NSObject protocol");
}