Различия между интерфейсами Java и протоколами Objective-C? - PullRequest
91 голосов
/ 13 июня 2009

Я знаю Java, и теперь я изучаю Objective-C. В чем именно заключаются различия между интерфейсами Java и протоколами Objective-C?

Ответы [ 2 ]

81 голосов
/ 13 июня 2009

Прежде всего, немного исторический взгляд на тему от одного из создателей Java. Далее, в Википедии есть довольно полезный раздел о протоколах Objective-C . В частности, следует понимать, что Objective-C поддерживает как формальные протоколы (которые явно объявлены с ключевым словом @protocol, эквивалентным интерфейсу Java), так и неформальные протоколы (только один или больше методов, реализованных классом, которые можно обнаружить с помощью отражения).

Если вы примете формальный протокол (терминология Objective C для «реализации интерфейса»), компилятор выдаст предупреждения для нереализованных методов, как вы ожидаете в Java. В отличие от Java (как упоминалось skaffman ), если класс Objective-C реализует методы, содержащиеся в формальном протоколе, говорят, что он «соответствует» этому протоколу, даже если его интерфейс не явно принять его. Вы можете проверить соответствие протокола в коде (используя -conformsToProtocol: ) следующим образом:

if ([myObject conformsToProtocol:@protocol(MyProtocol)]) {
    ...
}

ПРИМЕЧАНИЕ: документация Apple гласит:

"Этот метод определяет соответствие исключительно на основе формальных объявлений в заголовочных файлах, как показано выше. Он не проверяет, действительно ли реализованы методы, объявленные в протоколе, - это ответственность программиста."

Начиная с Objective-C 2.0 (в OS X 10.5 «Леопард» и iOS), формальные протоколы теперь могут определять необязательные методы , и класс соответствует протоколу, если он реализует все необходимые методы. Вы можете использовать ключевые слова @required (по умолчанию) и @optional, чтобы переключать, должны ли объявления методов, следующие за , или , могут быть реализованы для соответствия протоколу. (См. Раздел руководства Apple Objective-C 2.0 Language , в котором обсуждаются дополнительные методы протокола .)

Дополнительные методы протокола открывают большую гибкость для разработчиков, особенно для реализации делегатов и слушателей . Вместо того, чтобы расширять что-то вроде MouseInputAdapter (что может раздражать, поскольку Java также является одиночным наследованием) или реализовывать множество бессмысленных, пустых методов, вы можете принять протокол и реализовать только дополнительные методы, которые вам нужны. около. С этим шаблоном вызывающая сторона проверяет, реализован ли метод, прежде чем вызывать его (используя -respondsToSelector ) следующим образом:

if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) {
    [myObject fillArray:anArray withObject:foo];
    ...
}

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

18 голосов
/ 13 июня 2009

Они практически идентичны. Однако одна вещь, которая меня поразила, это то, что если вы явно не заявите, что целевой протокол C также реализует NSObject, ссылки на этот протокол не получат доступ к методам, которые объявляет NSObject (в любом случае без предупреждения компилятора). С помощью Java вы можете иметь ссылку на интерфейс, и при этом вызывать toString () и т.д. на нем.

например

Цель C:

@protocol MyProtocol
// Protocol definition
@end

id <MyProtocol> myProtocol;

 [myProtocol retain] // Compiler warning

Java

public interface MyInterface {
// interface definition
}

MyInterface myInterface;

myInterface.toString();  // Works fine.

Цель C (фиксированная):

@protocol MyProtocol <NSObject>
// Protocol definition
@end

id <MyProtocol> myProtocol;

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