Je connais Java et j'apprends maintenant Objective-C. Quelles sont exactement les différences entre les interfaces Java et les protocoles Objective-C?
la source
Je connais Java et j'apprends maintenant Objective-C. Quelles sont exactement les différences entre les interfaces Java et les protocoles Objective-C?
Tout d'abord, un petit point de vue historique sur le sujet , d'un des créateurs de Java. Ensuite, Wikipedia a une section modérément utile sur les protocoles Objective-C . En particulier, comprenez qu'Objective-C prend en charge à la fois les protocoles formels (qui sont explicitement déclarés avec le @protocol
mot - clé, l'équivalent d'une interface Java) et les protocoles informels (juste une ou plusieurs méthodes implémentées par une classe, qui peuvent être découvertes par réflexion).
Si vous adoptez un protocole formel (terminologie Objective-C pour «implémenter une interface»), le compilateur émettra des avertissements pour les méthodes non implémentées, comme vous vous en doutez en Java. Contrairement à Java (comme skaffman l'a mentionné), si une classe Objective-C implémente les méthodes contenues dans un protocole formel, elle est dite «conforme» à ce protocole, même si son interface ne l'adopte pas explicitement.Vous pouvez tester la conformité du protocole dans le code (en utilisant -conformsToProtocol:) comme ceci:
if ([myObject conformsToProtocol:@protocol(MyProtocol)]) {
...
}
REMARQUE: la documentation d'Apple indique:
"Cette méthode détermine la conformité uniquement sur la base des déclarations formelles dans les fichiers d'en-tête, comme illustré ci-dessus. Elle ne vérifie pas si les méthodes déclarées dans le protocole sont réellement implémentées - c'est la responsabilité du programmeur."
Depuis Objective-C 2.0 (sous OS X 10.5 "Leopard" et iOS), les protocoles formels peuvent désormais définir des méthodes optionnelles , et une classe est conforme à un protocole tant qu'elle implémente toutes les méthodes requises. Vous pouvez utiliser les mots clés @required
(par défaut) et @optional
pour indiquer si les déclarations de méthode qui suivent doivent ou peuvent être implémentées pour se conformer au protocole. (Voir la section du guide du langage de programmation Objective-C 2.0 d'Apple qui traite des méthodes de protocole facultatives .)
Les méthodes de protocole facultatives offrent une grande flexibilité aux développeurs, en particulier pour l'implémentation des délégués et des écouteurs . Au lieu d'étendre quelque chose comme un MouseInputAdapter (ce qui peut être ennuyeux, puisque Java est également un héritage unique) ou d'implémenter beaucoup de méthodes vides et inutiles, vous pouvez adopter un protocole et implémenter uniquement les méthodes facultatives qui vous intéressent. Avec ce modèle, l'appelant vérifie si la méthode est implémentée avant de l'appeler (en utilisant -respondsToSelector ) comme ceci:
if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) {
[myObject fillArray:anArray withObject:foo];
...
}
Si la surcharge de réflexion devient un problème, vous pouvez toujours mettre en cache le résultat booléen pour réutilisation , mais résistez à l'envie d'optimiser prématurément. :-)
-conformsToProtocol:
ne retournera OUI que si la classe adopte explicitement le protocole. Avez-vous même essayé?-conformsToProtocol:
faut en effet que la classe (ou un ancêtre) déclare formellement qu'elle adopte le protocole. Je ne sais pas comment je me suis trompé, merci pour la correction!Ils sont presque identiques. Cependant, la seule chose qui m'a surpris, c'est qu'à moins que vous ne déclariez explicitement qu'un protocole objectif C implémente également NSObject, les références à ce protocole n'ont pas accès aux méthodes déclarées par NSObject (sans avertissement du compilateur de toute façon). Avec java, vous pouvez avoir une référence à une interface, et toujours appeler toString (), etc.
par exemple
Objectif c:
Java:
Objectif C (fixe):
la source