Conosco Java e ora sto imparando Objective-C. Quali sono esattamente le differenze tra le interfacce Java e i protocolli Objective-C?
Conosco Java e ora sto imparando Objective-C. Quali sono esattamente le differenze tra le interfacce Java e i protocolli Objective-C?
Risposte:
Prima di tutto, una piccola prospettiva storica sull'argomento , da uno dei creatori di Java. Successivamente, Wikipedia ha una sezione moderatamente utile sui protocolli Objective-C . In particolare, tieni presente che Objective-C supporta sia protocolli formali (che vengono dichiarati esplicitamente con la @protocolparola chiave, l'equivalente di un'interfaccia Java) che protocolli informali (solo uno o più metodi implementati da una classe, che possono essere scoperti tramite riflessione).
Se si adotta un protocollo formale (terminologia Objective-C per "implementare un'interfaccia"), il compilatore emetterà avvisi per metodi non implementati, proprio come ci si aspetterebbe in Java. A differenza di Java (come menzionato da skaffman ), se una classe Objective-C implementa i metodi contenuti in un protocollo formale, si dice "conforme" a quel protocollo, anche se la sua interfaccia non lo adotta esplicitamente.Puoi testare la conformità del protocollo nel codice (usando -conformsToProtocol :) in questo modo:
if ([myObject conformsToProtocol:@protocol(MyProtocol)]) {
...
}
NOTA: la documentazione di Apple afferma:
"Questo metodo determina la conformità esclusivamente sulla base delle dichiarazioni formali nei file di intestazione, come illustrato sopra. Non controlla se i metodi dichiarati nel protocollo sono effettivamente implementati: questa è la responsabilità del programmatore".
A partire da Objective-C 2.0 (in OS X 10.5 "Leopard" e iOS), i protocolli formali possono ora definire metodi opzionali e una classe è conforme a un protocollo fintanto che implementa tutti i metodi richiesti. È possibile utilizzare @required(predefinito) e le @optionalparole chiave per stabilire se le dichiarazioni di metodo che seguono devono o possono essere implementate per essere conformi al protocollo. (Consulta la sezione della guida del linguaggio di programmazione Objective-C 2.0 di Apple che illustra i metodi di protocollo opzionali .)
I metodi di protocollo opzionali offrono molta flessibilità agli sviluppatori, in particolare per l'implementazione di delegati e ascoltatori . Invece di estendere qualcosa come un MouseInputAdapter (che può essere fastidioso, poiché Java è anche un'ereditarietà singola) o implementare molti metodi inutili e vuoti, puoi adottare un protocollo e implementare solo i metodi opzionali che ti interessano. Con questo modello, il chiamante controlla se il metodo è implementato prima di invocarlo (usando -respondsToSelector ) in questo modo:
if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) {
[myObject fillArray:anArray withObject:foo];
...
}
Se il sovraccarico della riflessione diventa un problema, puoi sempre memorizzare nella cache il risultato booleano per il riutilizzo , ma resistere all'impulso di ottimizzare prematuramente. :-)
-conformsToProtocol:restituirà YES solo se la classe adotta esplicitamente il protocollo. L'hai mai provato?
-conformsToProtocol:effetti richiede che la classe (o un antenato) dichiari formalmente di adottare il protocollo. Non sono sicuro di come ho sbagliato, grazie per la correzione!
Sono quasi identici. Tuttavia, l'unica cosa che mi ha colto di sorpresa, è che, a meno che tu non dichiari esplicitamente che un protocollo C oggettivo implementa anche NSObject, i riferimenti a quel protocollo non ottengono l'accesso ai metodi dichiarati da NSObject (senza comunque un avviso del compilatore). Con java puoi avere un riferimento a un'interfaccia e chiamare comunque toString () ecc. Su di essa.
per esempio
Obiettivo C:
@protocol MyProtocol
// Protocol definition
@end
id <MyProtocol> myProtocol;
[myProtocol retain] // Compiler warning
Giava:
public interface MyInterface {
// interface definition
}
MyInterface myInterface;
myInterface.toString(); // Works fine.
Obiettivo C (fisso):
@protocol MyProtocol <NSObject>
// Protocol definition
@end
id <MyProtocol> myProtocol;
[myProtocol retain] // No Warning