Next: Héritage et polymorphisme vertical
Up: Panoramique et comparaison de
Previous: Modularité
Cacher l'information
Dans les trois langages, on peut limiter l'accès aux variables d'instance et aux méthodes en utilisant les mots clefs suivants:
- private
- accessible seulement dans cette classe,
- protected
- accessible seulement dans cette classe et ses sous-classes,
- public
- accessible partout.
Cependant, C++ et Java disposent aussi d'un quatrième niveau, qu'on appelle le niveau des friends. Cela revient à permettre l'accès aux données à toute classe, fonction ou méthode qui est un friend (une amie), mais qui n'a aucune relation avec l'héritage. En C++ cela se fait en définissant explicitement à l'intérieur d'une classe les noms de ces privilégiés, comme dans
class ColorPoint: public Point { private int color; ... friend void antialias (ColorPoint c,ColorPoint d); ... }void antialias (ColorPoint c,ColorPoint d) { c->color=(c->color+d->color)/2; }
En C++, toute donnée est par défaut private, tandis qu'en Objective-C ell'est
par défaut public et en Java accessible aux amis, mais à différence de
C++, en Java on considère friend seulement les méthodes qui sont dans
le même package.
Le choix du niveau d'accessibilité n'est pas facile: toute donnée déclarée
private est effectivement invisible aux sous-classes, ce qui protège les
sous-classes de tout changement apporté à la classe de base, mais cela signifie
aussi que pour accéder à ces données les sous-classes doivent passer par une
interface composée de méthodes, et cela nuit à l'efficacité. C'est là qu'on doit
déjà commencer à choisir comment mélanger ADT et OO.
Un bon exemple de ce dilemme se retrouve dans un fragment de programme comme
celui-ci:
class IntList { ??? int data[]; ... public hd { return data[0];} ... } class OrdIntList extends IntList { ... public sortAscending { ??? } }Si on veut protéger l'implémentation de IntList, on ne pourra pas savoir que les données sont rangées dans un vecteur, ce qui nous empêchera d'utiliser un algorithme de tri efficace dans OrdIntList. Si par contre on ne la protège pas, on pourra être efficace dans OrdIntList, mais tout changement de représentation dans IntList se propagera aussi dans OrdIntList.
Dans ce cas spécifique, la meilleure solution semble être de garder l'implémentation protégée, et de fournir dans IntList des méthodes
public asVector: { // renvoie une repr\'esentation de la liste comme vecteur } public fromVector: { // initialise la liste a partir d'un vecteur }Ces méthodes donneront un accès efficace pour des opérations de tri, sans casser la barrière de modularité.
Next: Héritage et polymorphisme vertical Up: Panoramique et comparaison de Previous: Modularité Roberto DiCosmo
Mon Jun 3 18:29:31 MET DST 1996