¿Diferencias entre las interfaces Java y los protocolos Objective-C?

Conozco Java y ahora estoy aprendiendo Objective-C. ¿Cuáles son exactamente las diferencias entre las interfaces Java y los protocolos Objective-C?

Primero, una pequeña perspectiva histórica sobre el tema , de uno de los creadores de Java. Luego, Wikipedia tiene una sección medianamente útil sobre los protocolos de Objective-C . En particular, comprenda que Objective-C admite tanto protocolos formales (que se declaran explícitamente con la palabra clave @protocol , el equivalente de una interfaz Java) como protocolos informales (solo uno o más métodos implementados por una clase, que se pueden descubrir mediante la reflexión )

Si adopta un protocolo formal (terminología de Objective-C para “implementar una interfaz”), el comstackdor emitirá advertencias para los métodos no implementados, tal como se esperaría en Java. A diferencia de Java (como se menciona skaffman ), si una clase Objective-C implementa los métodos contenidos en un protocolo formal, se dice que “se ajusta” a ese protocolo, incluso si su interfaz no lo adopta explícitamente. Puede probar la conformidad del protocolo en el código (usando -conformsToProtocol:) de esta manera:

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

NOTA: La documentación de Apple establece:

“Este método determina la conformidad únicamente sobre la base de las declaraciones formales en los archivos de encabezado, como se ilustra arriba. No verifica si los métodos declarados en el protocolo se implementan realmente, esa es la responsabilidad del progtwigdor”.

A partir de Objective-C 2.0 (en OS X 10.5 “Leopard” e iOS), los protocolos formales ahora pueden definir métodos opcionales , y una clase se ajusta a un protocolo siempre que implemente todos los métodos requeridos. Puede usar las palabras clave @required (predeterminado) y @optional para alternar si las declaraciones de métodos que siguen deben o deben implementarse para cumplir con el protocolo. (Consulte la sección de la guía del lenguaje de progtwigción Objective-C 2.0 de Apple que trata sobre los métodos de protocolo opcionales ).

Los métodos de protocolo opcionales abren una gran flexibilidad a los desarrolladores, particularmente para implementar delegates y oyentes . En lugar de extender algo como MouseInputAdapter (que puede ser molesto, ya que Java también es de herencia única) o implementar muchos métodos inútiles y vacíos, puede adoptar un protocolo e implementar solo los métodos opcionales que le interesan. Con este patrón, la persona que llama comprueba si el método se implementó antes de invocarlo (usando -respondsToSelector ) de esta manera:

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

Si la sobrecarga de la reflexión se convierte en un problema, siempre puede almacenar en caché el resultado booleano para su reutilización , pero resiste el impulso de optimizarlo prematuramente. 🙂

Ellos son casi idénticos. Sin embargo, lo único que me ha sorprendido es que, a menos que declare explícitamente que un protocolo Object C también implementa NSObject, las referencias a ese protocolo no tienen acceso a los métodos que declara NSObject (sin una advertencia de comstackdor de todos modos). Con java puede tener una referencia a una interfaz, y todavía llamar a String (), etc. en él.

p.ej

C objective:

 @protocol MyProtocol // Protocol definition @end id  myProtocol; [myProtocol retain] // Compiler warning 

Java:

 public interface MyInterface { // interface definition } MyInterface myInterface; myInterface.toString(); // Works fine. 

Objetivo C (fijo):

 @protocol MyProtocol  // Protocol definition @end id  myProtocol; [myProtocol retain] // No Warning