web-dev-qa-db-fra.com

Différences entre les interfaces Java et les protocoles Objective-C?

Je connais Java, et maintenant j'apprends Objective-C. Quelles sont exactement les différences entre les interfaces Java et les protocoles Objective-C?

92
Arne Evertsson

Tout d'abord, un peu perspective historique sur le sujet , de l'un des créateurs de Java. Ensuite, Wikipedia a un moyen modérément utile section sur les protocoles Objective-C . En particulier, comprenez que Objective-C prend en charge les deux protocoles formels (qui sont explicitement déclarés avec le @protocol mot clé, l'équivalent d'un Java interface) et protocoles informels (juste une ou plusieurs méthodes implémentées par un , qui peut être découvert 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 y attendriez en Java. Contrairement à Java (comme skaffman mentionné), si une classe Objective-C implémente les méthodes contenues dans un protocole formel, il est dit "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: 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 mises en œuvre - 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 se conforme à un tant qu'il met en œuvre toutes les méthodes requises. Vous pouvez utiliser le @required (par défaut) et @optional mots-clés pour basculer si les déclarations de méthode qui suivent doivent ou peuvent être mis en œuvre pour se conformer au protocole. (Voir la section du guide langage de programmation Objective-C 2. d'Apple qui explique méthodes de protocole facultatives .)

Les méthodes de protocole facultatives offrent beaucoup de flexibilité aux développeurs, en particulier pour implémenter les délégués et les auditeurs . Au lieu d'étendre quelque chose comme un MouseInputAdapter (ce qui peut être ennuyeux, car Java est également à héritage unique) ou implémentant de nombreuses méthodes vides et inutiles, vous pouvez adopter un protocole et implémentez uniquement les méthodes optionnelles qui vous intéressent. Avec ce modèle, l'appelant vérifie si la méthode est implémentée avant de l'invoquer (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 une réutilisation , mais résister à l'envie d'optimiser prématurément. :-)

81
Quinn Taylor

Ils sont presque identiques. Cependant, la seule chose qui m'a frappé, c'est qu'à moins que vous ne déclariez explicitement qu'un protocole Objective C implémente également NSObject, les références à ce protocole n'obtiennent pas l'accès aux méthodes que NSObject déclare (sans avertissement de compilation de toute façon). Avec Java vous pouvez avoir une référence à une interface, et toujours appeler toString () etc dessus).

par exemple

Objectif 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.

Objectif C (fixe):

@protocol MyProtocol <NSObject>
// Protocol definition
@end

id <MyProtocol> myProtocol;

[myProtocol retain] // No Warning
18
Tom Jefferys