Next: La gestion des messages Up: Définir une classe Previous: Accès aux variables d'instance

La portée des variables d'instance

Bien que déclarée dans l'interface les variables d'instance sont plus une question d'implémentation que d'utilisation. L'interface d'un objet dépend plus de ces méthodes que de la structure de ses données. Il y a souvent une correspondance entre une méthode et une variable comme dans l'exemple suivant:

- (int)tag
{
return tag;
}
Mais ce n'est pas obligatoire. Des méthodes peuvent retourner des informations qui ne sont pas contenues dans les variables d'instances et certaines variables d'instance peuvent contenir des informations que l'objet ne veut pas révéler.

A longueur des révisions d'une classe, le choix des variables d'instance peut changer, bien que les méthodes déclarées restent inchangées. Tant que les messages sont le véhicules des interactions avec les instances, ces changements n'affecterons pas son interface.

Pour assurer l'encapsulation des variables d'instances, le compilateur limite leurs portée. Mais pour plus de flexibilité, il permet de spécifier la portée sur trois niveau différents comme c'est illustré Figure 5.

Figure 5. La portée des variables d'instance

Chaque niveau est indiqué par une directive de compilation.

Directive Sens

@private
La variable d'instance n'est accessible que dans la classe qui la déclare.

@protected
La variable d'instance n'est accessible que dans la classe qui la déclare et dans les classes qui en hérite.

@public
La variable d'instance est accessible de partout.

Une directive s'applique a toutes les variables d'instance listé après, jusqu'à la prochaine directive ou la fin de la liste. Dans l'exemple suivant, les instances squelette et placard sont privées, gardeAVue est protégée, invitation public.
@interface UneClass : Object
{
@private
id squelette;
float placard;
@protected
int gardeAVue;
@public
char * invitation;
}
Par défaut les variables sont protégée (@protected). Toutes les variables d'instance qu'une classe déclare (quelque soit la directive) sont visible dans l'implémentation de la classe elle même. Par exemple, une classe qui déclare une variable d'instance capitaine, peut y référer dans une définition de méthode:
- remplacerCapitaine: leNouveau
{
id leVieux = capitaine;
capitaine = leNouveau;
return leVieux;
}
Il est clair que si une classe ne pouvai pas accéder à ces propres variables d'instance, celles ci seraient sans aucune utilité.

Normalement, une classe a aussi accès aux variables d'instance dont elle hérite. Il est naturel que l'ensemble de la structure de donnée de l'objet soit dans la portée des méthodes de la classe, surtout si vous pensez profiter de l'héritage. La possibilité de manipuler une variable est en général hérité avec celle ci. La méthode remplacerCapitaine: peut être définie dans toute classe qui hérite de la variable capitaine.

Des raisons pour lesquelles vous voudriez retirer l'accès d'une variable aux sous classes:

Pour limiter la portée d'une variable à la classe qui la déclare utiliser la directive @private.

A l'autre extrême, déclarer une variable @public, lui donne une porté générale (comme le champ d'une structure C). Normalement pour connaître la valeur d'une variable d'instance, on envoi un message demandant l'information. Pour les variables publiques on peu y accédé avec la même syntaxe que pour un champ de structure en langage C.

UneClass *mutin = [[UneClass alloc] init]; mutin->captain = nil;

Remarquer que l'objet doit être statiquement typé.

Rendre une variable d'instance @public va à l'encontre du principe d'encapsulation, ou les objets protègent leurs variables contre la lecture et les erreurs d'inadvertance. Les variables publiques doivent donc être évitées au maximum sauf dans des cas particuliers extraordinaires.

Next: La gestion des messages Up: Définir une classe Previous: Accès aux variables d'instance

Dominique REVUZ
Vendredi 21 février 1997 17:27:12
Une Bug Un mail Merci