Можно ли наследовать протоколы и категории Objective-C?

Я немного запутался в некоторых концепциях протоколов и категорий Objective-C.

Могут ли протоколы и категории наследоваться подклассами в Objective-C?


person Rajender Kumar    schedule 19.09.2011    source источник


Ответы (5)


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

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

Сами протоколы могут быть расширены для создания новых протоколов. состоящий из надмножества методов исходного протокола. Фактически, точно так же, как большинство классов наследуются от класса NSObject, большинство протоколов расширяют протокол NSObject (имена протоколов и имена классов находятся в разных пространствах имен). Это сделано для того, чтобы объекты, объявленные как id<WhateverProtocol>, могли отправлять базовые сообщения, такие как -retain, -release и т. д., без генерации предупреждений компилятором.

person JeremyP    schedule 19.09.2011
comment
Популярным примером может быть: @protocol UITableViewDelegate ‹NSObject, UIScrollViewDelegate›. - person Sunil Chauhan; 21.05.2014

Категории подобны расширению класса. Вы можете добавлять свои собственные методы в другие классы (такие как NSString или что-то еще). Это означает, что любой подкласс также получает методы.

Принимая во внимание, что протокол представляет собой список методов, которые требуют, чтобы класс, который подтверждает его, реализовывал все это (если только он не использует тег @Optional). Таким образом, нет смысла наследовать его подкласс.

Изменить:

Что касается реализации протокола, я понял, что недостаточно ясно выразился. Методы протокола, которые были реализованы в его суперклассе, могут наследоваться, однако я имел в виду, что обычно вам не нужно переопределять метод протокола вашего суперкласса.

person TheAmateurProgrammer    schedule 19.09.2011
comment
Более конкретно: подкласс наследует соответствие протоколу своего родителя. Таким образом, если класс соответствует ‹SomeProtocol›, то его подклассы также соответствуют ‹SomeProtocol›. - person Rob Napier; 19.09.2011
comment
Да, это то, что я говорил. Спасибо. - person TheAmateurProgrammer; 19.09.2011

Ваш вопрос не ясен. Вы можете спросить, наследуют ли подклассы протоколы и категории своего суперкласса. @theAmateurProgrammer ответил на это.

Вы также можете спросить, могут ли сами категории и протоколы наследовать от других категорий и протоколов. Для категорий ответ отрицательный. Для протоколов ответ положительный, и на самом деле протоколы почти всегда должны наследоваться точно так же, как и классы:

@protocol SomeProtocol <NSObject>
...
@end

Это говорит о том, что все, что соответствует <SomeProtocol>, также соответствует <NSObject> (который является протоколом, а также классом). Это позволяет вам вызывать такие методы, как respondsToSelector:, что очень важно для большинства реализаций протокола.

person Rob Napier    schedule 19.09.2011
comment
половина этого ответа является комментарием к исходному вопросу. С другой стороны, это ответило на мой вопрос на сегодня, так что +1. Спасибо. - person Dan Rosenstark; 07.07.2012

Протоколы похожи на интерфейсы в Java. Итак, класс предоставляет протокол для доступа к нему.

Вы можете «подклассировать» протоколы так же, как в Java вы можете «подклассировать» интерфейсы.

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

Это очень полезно, потому что позволяет избежать создания большой хрупкой иерархии подклассов.

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

Однако следует иметь в виду, что когда вы добавляете методы в категорию — о чем мне напомнили коллеги по работе — вы делаете эти методы доступными повсюду. Я читал в нескольких местах, что распространенная ошибка новичков состоит в том, что они сходят с ума по категориям, используя их все время вместо того, чтобы создавать новые классы, которые выполняли бы эту работу.

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

person Max MacLeod    schedule 19.09.2011

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");
}
person onmyway133    schedule 11.08.2014