Подтвердить что ты не робот

Протокол против категории

Может ли кто-нибудь объяснить различия между Протоколы и Категории в Objective-C? Когда вы используете один над другим?

4b9b3361

Ответ 1

Протокол - это то же самое, что и интерфейс в Java: это, по сути, контракт, который гласит: "Любой класс, который реализует этот протокол, также будет реализовывать эти методы".

С другой стороны, категория просто связывает методы с классом. Например, в Cocoa я могу создать категорию для NSObject, которая позволит мне добавлять методы в класс NSObject (и, конечно же, все подклассы), хотя я на самом деле не имеют доступа к NSObject.

Подводя итог: протокол определяет, какие методы будет реализован классом; категория добавляет методы к существующему классу.

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

Ответ 2

В протоколе говорится: "Вот некоторые методы, которые я хотел бы вам реализовать". В категории говорится: "Я расширяю функциональность этого класса с помощью этих дополнительных методов".

Теперь я подозреваю, что ваше замешательство проистекает из использования Apple фразы "неофициальный протокол". Здесь ключевая (и самая запутанная) точка: неофициальный протокол фактически не является протоколом вообще. Это фактически категория в NSObject. Cocoa использует распространенные неофициальные протоколы для предоставления интерфейсов для делегатов. Поскольку синтаксис @protocol не допускал дополнительных методов до Objective-C 2.0, Apple внедрила необязательные методы, чтобы ничего не делать (или возвращать фиктивное значение) и требуемые методы для исключения исключения. Невозможно обеспечить выполнение этого с помощью компилятора.

Теперь с Objective-C 2.0 синтаксис @protocol поддерживает ключевое слово @optional, отмечая некоторые методы в протоколе как необязательные. Таким образом, ваш класс соответствует протоколу, если он реализует все методы, отмеченные как @required. Компилятор может определить, реализует ли ваш класс все необходимые методы, что является огромной экономией времени. IPhone SDK использует исключительно синтаксис Objective-C 2.0 @protocol, и я не могу придумать, чтобы не использовать его в каких-либо новых разработках (кроме Mac OS X Cocoa приложений, которые должны запускаться в более ранних версиях Mac OS X).

Ответ 3

Категории:

Категория - это способ добавления новых методов ко всем экземплярам существующего класса без изменения самого класса.

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

Предположим, вы используете NSView объекты в cocoa, и вы обнаружите, что хотите, чтобы все экземпляры NSView могли выполнить какое-либо действие. Очевидно, вы не можете переписать класс NSView, и даже если вы выйдете из него, не все объекты NSView в вашей программе будут иметь ваш производный тип. Решением является создание категории на NSView, которую вы затем используете в своей программе. Пока вы #import заголовочный файл, содержащий объявление категории, будет выглядеть так, как будто каждый NSView объект отвечает на методы, определенные вами в исходном файле catagory.

Протоколы:

Протокол представляет собой набор методов, которые может выбрать любой класс.

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

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

Боковое примечание: язык objective-c не поддерживает множественное наследование (класс может выводиться только из одного суперкласса), но многие из тех же функций могут предоставляться протоколами, потому что класс может соответствовать нескольким различным протоколам.

Ответ 4

Насколько я понимаю, протоколы немного похожи на интерфейсы Java. Протоколы объявляют методы, но реализация зависит от каждого класса. Категории, похоже, похожи на Ruby mixins. С помощью категорий вы можете добавлять методы к существующим классам. Даже встроенные классы.

Ответ 5

Протокол позволяет объявлять список методов, которые не ограничиваются каким-либо конкретным классом или категориями. Методы, объявленные в протоколе, могут быть приняты любым классом/категориями. Класс или категория, которая принимает протокол, должна реализовать все необходимые методы, объявленные в протоколе.

Категория позволяет добавлять дополнительные методы к существующему классу, но они не позволяют добавлять дополнительные переменные экземпляра. Методы добавления категории становятся частью типа класса.

Ответ 6

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

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

NSString *test = @"Leet speak";
NSString *leet = [test stringByConvertingToLeet];

Ответ 7

Определения от С. Г. Кочана "Программирование в Objective-C":

Категория:

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

Протоколы:

Протокол - это список методов, разделяемых между классами. Методы, перечисленные в протоколе, не имеют соответствующих реализаций; theyre должен был быть реализован кем-то другим (как вы!). Протокол предоставляет способ определения набора методов, которые каким-то образом связаны с указанным именем. Методы обычно документируются так, что вы знаете, как они должны выполняться, и чтобы вы могли реализовать их в своих определениях классов, если это необходимо. Протокол перечисляет набор методов, некоторые из которых вы можете реализовать, и другие, которые вы должны реализовать. Если вы решите внедрить все необходимые методы для определенного протокола, вы, как утверждается, должны принять или принять этот протокол. Вы можете определить протокол, в котором все методы являются необязательными, или где требуется все.