Ich kenne Java und lerne jetzt Objective-C. Was genau sind die Unterschiede zwischen Java-Schnittstellen und Objective-C-Protokollen?
quelle
Ich kenne Java und lerne jetzt Objective-C. Was genau sind die Unterschiede zwischen Java-Schnittstellen und Objective-C-Protokollen?
Zunächst eine kleine historische Perspektive zu diesem Thema von einem der Entwickler von Java. Als nächstes hat Wikipedia einen mäßig hilfreichen Abschnitt über Objective-C-Protokolle . Beachten Sie insbesondere, dass Objective-C sowohl formale Protokolle (die explizit mit dem @protocol
Schlüsselwort deklariert werden, das einer Java-Schnittstelle entspricht) als auch informelle Protokolle (nur eine oder mehrere von einer Klasse implementierte Methoden, die durch Reflektion ermittelt werden können) unterstützt.
Wenn Sie ein formales Protokoll verwenden (Objective-C-Terminologie für "Implementieren einer Schnittstelle"), gibt der Compiler Warnungen für nicht implementierte Methoden aus, wie Sie es in Java erwarten würden. Im Gegensatz zu Java (wie von Skaffman erwähnt) wird eine Objective-C-Klasse, wenn sie die in einem formalen Protokoll enthaltenen Methoden implementiert, als "konform" mit diesem Protokoll bezeichnet, auch wenn ihre Schnittstelle es nicht explizit übernimmt.Sie können die Protokollkonformität im Code (mit -conformsToProtocol :) wie folgt testen :
if ([myObject conformsToProtocol:@protocol(MyProtocol)]) {
...
}
HINWEIS: In der Dokumentation von Apple heißt es:
"Diese Methode bestimmt die Konformität ausschließlich auf der Grundlage der formalen Deklarationen in Header-Dateien, wie oben dargestellt. Sie prüft nicht, ob die im Protokoll deklarierten Methoden tatsächlich implementiert sind - das liegt in der Verantwortung des Programmierers."
Ab Objective-C 2.0 (in OS X 10.5 "Leopard" und iOS) können formale Protokolle jetzt optionale Methoden definieren , und eine Klasse entspricht einem Protokoll, solange alle erforderlichen Methoden implementiert sind. Mit den Schlüsselwörtern @required
(Standard) und können Sie @optional
umschalten, ob die folgenden Methodendeklarationen implementiert werden müssen oder dürfen , um dem Protokoll zu entsprechen. (Weitere Informationen finden Sie im Abschnitt des Objective-C 2.0-Programmiersprachenhandbuchs von Apple , in dem optionale Protokollmethoden erläutert werden .)
Optionale Protokollmethoden eröffnen Entwicklern viel Flexibilität, insbesondere bei der Implementierung von Delegaten und Listenern . Anstatt so etwas wie einen MouseInputAdapter zu erweitern (was ärgerlich sein kann, da Java auch eine Einzelvererbung ist) oder viele sinnlose, leere Methoden zu implementieren, können Sie ein Protokoll übernehmen und nur die optionalen Methoden implementieren, die Sie interessieren. Mit diesem Muster prüft der Aufrufer, ob die Methode implementiert ist, bevor er sie aufruft (mit -respondsToSelector ).
if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) {
[myObject fillArray:anArray withObject:foo];
...
}
Wenn der Overhead der Reflexion zu einem Problem wird, können Sie das boolesche Ergebnis jederzeit zur Wiederverwendung zwischenspeichern , aber dem Drang widerstehen, vorzeitig zu optimieren. :-)
-conformsToProtocol:
gibt nur JA zurück, wenn die Klasse das Protokoll explizit übernimmt. Hast du es überhaupt versucht?-conformsToProtocol:
erfordert in der Tat, dass die Klasse (oder ein Vorfahr) offiziell erklärt, dass sie das Protokoll übernimmt. Ich bin mir nicht sicher, wie ich das falsch verstanden habe, danke für die Korrektur!Sie sind fast identisch. Was mich jedoch aufgefallen ist, ist, dass Verweise auf dieses Protokoll keinen Zugriff auf die von NSObject deklarierten Methoden erhalten, sofern Sie nicht ausdrücklich erklären, dass ein objektives C-Protokoll auch NSObject implementiert (ohnehin ohne Compiler-Warnung). Mit Java können Sie einen Verweis auf eine Schnittstelle haben und trotzdem toString () usw. aufrufen.
z.B
Ziel c:
Java:
Ziel C (fest):
quelle