Различия между интерфейсами 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