Я знаю Java, и теперь изучаю Objective-C. Каковы различия между интерфейсами Java и протоколами Objective-C?
Различия между интерфейсами Java и протоколами Objective-C?
Ответ 1
Прежде всего, немного историческая перспектива по теме, от одного из создателей Java. Далее, Wikipedia имеет умеренно полезный раздел в Objective-C протоколах. В частности, поймите, что Objective-C поддерживает как формальные протоколы (которые явно объявлены с ключевым словом @protocol
, эквивалентом интерфейса Java) и неофициальными протоколами (просто один или несколько методов, реализуемых классом, которые могут быть обнаружены с помощью отражения).
Если вы примете формальный протокол (терминология Objective-C для "реализации интерфейса" ), компилятор будет выдавать предупреждения для нереализованных методов, как и следовало ожидать в Java. В отличие от Java (в качестве skaffman), если класс Objective-C реализует методы, содержащиеся в формальном протоколе, считается, что он "соответствует" этому протоколу, даже если его интерфейс не работает, t явно принять его. Вы можете протестировать соответствие протокола в коде (используя - соответствуетToProtocol:) следующим образом:
if ([myObject conformsToProtocol:@protocol(MyProtocol)]) {
...
}
ПРИМЕЧАНИЕ. Apple documentation заявляет:
"Этот метод определяет соответствие только на основе формальных объявлений в заголовочных файлах, как показано выше. Он не проверяет, действительно ли реализованы методы, объявленные в протоколе, - это ответственность программистов."
Как и в случае с Objective-C 2.0 (в OS X 10.5 "Leopard" и iOS) формальные протоколы теперь могут определять необязательные методы, а класс соответствует протоколу, если он реализует все требуемые методы. Вы можете использовать ключевые слова @required
(по умолчанию) и @optional
для переключения, должны ли быть реализованы объявления метода, которые следуют должны или , чтобы соответствовать протоколу. (См. Раздел руководства Apple Objective-C 2.0 Programming Language, в котором обсуждается необязательный протокольные методы.)
Дополнительные методы протокола открывают большую гибкость для разработчиков, особенно для реализации делегатов и слушателей. Вместо того, чтобы расширять что-то вроде MouseInputAdapter (что может раздражать, так как Java также является однонаправленным) или реализует много бессмысленных, пустых методы, вы можете принять протокол и реализовать только дополнительные методы, о которых вы заботитесь. С помощью этого шаблона вызывающий абонент проверяет, реализуется ли этот метод перед его вызовом (используя - отвечаетSoSelector) следующим образом:
if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) {
[myObject fillArray:anArray withObject:foo];
...
}
Если накладные расходы на отражение становятся проблемой, вы всегда можете кэшировать логический результат для повторного использования, но сопротивляться желанию оптимизировать преждевременно.: -)
Ответ 2
Они почти идентичны. Однако одна вещь, которая меня поймала, заключается в том, что, если вы явно не объявляете, что объективный протокол 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