Une extension de classe présente certaines similitudes avec une catégorie, mais elle ne peut être ajoutée qu'à une classe dont vous avez le code source au moment de la compilation (la classe est compilée en même temps que l'extension de classe). Les méthodes déclarées par une extension de classe sont implémentées dans le bloc @implementation de la classe d'origine. Vous ne pouvez donc pas, par exemple, déclarer une extension de classe sur une classe de framework, telle qu'une classe Cocoa ou Cocoa Touch comme NSString.
La syntaxe pour déclarer une extension de classe est similaire à la syntaxe pour une catégorie, et ressemble à ceci :
@interface ClassName ()
@end
Comme aucun nom n'est donné entre parenthèses, les extensions de classe sont souvent appelées catégories anonymes.
Contrairement aux catégories ordinaires, une extension de classe peut ajouter ses propres propriétés et variables d'instance à une classe. Si vous déclarez une propriété dans une extension de classe, comme ceci :
@interface XYZAnimal () {
id _someCustomInstanceVariable;
}
...
@end
À mon avis, il est préférable de considérer les extensions de classe comme des interfaces privées d'une classe. L'interface primaire (dans votre fichier .h) agit comme l'interface publique qui définit le contrat comportemental de la classe avec les autres classes.
Utiliser les extensions de classe pour cacher des informations privées
Les extensions de classe sont souvent utilisées pour étendre l'interface publique avec des méthodes ou des propriétés privées supplémentaires à utiliser dans l'implémentation de la classe elle-même. Il est courant, par exemple, de définir une propriété comme readonly dans l'interface, mais comme readwrite dans une extension de classe déclarée au-dessus de l'implémentation, afin que les méthodes internes de la classe puissent modifier la valeur de la propriété directement.
Par exemple, la classe XYZPerson pourrait ajouter une propriété appelée uniqueIdentifier, conçue pour conserver la trace d'informations telles que le numéro de sécurité sociale aux États-Unis.
L'attribution d'un identifiant unique à un individu dans le monde réel nécessite généralement beaucoup de travail administratif. L'interface de la classe XYZPerson pourrait donc déclarer cette propriété comme étant en lecture seule et fournir une méthode permettant de demander l'attribution d'un identifiant, comme ceci :
@interface XYZPerson : NSObject
...
@property (readonly) NSString *uniqueIdentifier;
- (void)assignUniqueIdentifier;
@end
Pour que la classe XYZPerson puisse modifier la propriété en interne, il est logique de redéclarer la propriété dans une extension de classe définie en haut du fichier d'implémentation de la classe :
@property (readwrite) NSString *uniqueIdentifier;
Remarque : L'attribut readwrite est facultatif, car il s'agit de la valeur par défaut. Vous pouvez l'utiliser lorsque vous redéclarez une propriété, pour plus de clarté.