Composition des objets
CHAPITRE 11
240
nés ou, au contraire, recopier leur valeur. On voit donc apparaître la distinction entre ce que
l’on nomme :
• la copie superficielle d’un objet : on se contente de recopier la valeur de tous ses attributs,
y compris ceux de type classe (qui sont donc des références) ;
• la copie profonde d’un objet : comme précédemment, on recopie la valeurs des attributs
d’un type de base, mais pour les attributs de type classe, on crée une nouvelle référence à un
autre objet de même type et de même valeur.
Comme on s’en doute, la copie profonde peut être récursive ; autrement dit, un attribut de
type classe peut très bien, à son tour, renfermer d’autres attributs de type classe... On voit
d’ailleurs que, pour des objets complexes, il pourra exister des niveaux intermédiaires entre
copie profonde ou copie superficielle.
Dans le cas des langages gérant les objets par valeur, on notera que la copie induite par les
affectations ou la transmission par valeur des paramètres correspond à une copie profonde.
Mais ces langages permettent généralement de créer des objets hybrides en faisant cohabiter
des attributs de type classe (gérés par valeur) et des références à des objets ; dans ce cas, on
comprend que ces dernières ne sont plus soumises à une copie profonde. Généralement, le
programme peut alors fournir une méthode de son crû pour gérer convenablement (plus précisément, comme on le désire) cette copie, qu’elle soit induite par une affectation ou par le
passage en paramètre.
Exercice 11.4 Doter la classe Segment présentée au paragraphe 2, page 235, d’une méthode de copie superficielle et d’une méthode de copie profonde. Pour réaliser cette seconde
méthode, on prévoiera d’adapter la classe Point en la dotant d’une méthode de copie.
5 Une classe « singleton »
N.B. Ce paragraphe peut être ignoré dans un premier temps.
Jusqu’ici, nous avons rencontré des situations dans lesquelles une classe A contenait un attribut de type classe B. Mais il est également possible qu’une classe A renferme un attribut de ce
même type A.
Supposons par exemple qu’on l’on souhaite réaliser une classe nommée Singleton ne permettant d’instancier qu’un seul objet de sa classe. Plus précisément, on souhaite que chaque
tentative d’instanciation, à partir de la seconde, fournisse toujours la référence à un seul et
unique objet. Compte tenu de la manière dont fonctionne le constructeur et du fait qu’il ne
fournit pas de résultat, on voit qu’il n’est pas possible d’opérer cette gestion d’objet unique
dans le constructeur lui-même. Les demandes d’instanciation doivent donc être adressées à
une autre méthode de la classe Singleton que nous nommerons créeInstance et qui
doit :
• instancier un objet lors de son premier appel ;
CHAPITRE 11
240
nés ou, au contraire, recopier leur valeur. On voit donc apparaître la distinction entre ce que
l’on nomme :
• la copie superficielle d’un objet : on se contente de recopier la valeur de tous ses attributs,
y compris ceux de type classe (qui sont donc des références) ;
• la copie profonde d’un objet : comme précédemment, on recopie la valeurs des attributs
d’un type de base, mais pour les attributs de type classe, on crée une nouvelle référence à un
autre objet de même type et de même valeur.
Comme on s’en doute, la copie profonde peut être récursive ; autrement dit, un attribut de
type classe peut très bien, à son tour, renfermer d’autres attributs de type classe... On voit
d’ailleurs que, pour des objets complexes, il pourra exister des niveaux intermédiaires entre
copie profonde ou copie superficielle.
Dans le cas des langages gérant les objets par valeur, on notera que la copie induite par les
affectations ou la transmission par valeur des paramètres correspond à une copie profonde.
Mais ces langages permettent généralement de créer des objets hybrides en faisant cohabiter
des attributs de type classe (gérés par valeur) et des références à des objets ; dans ce cas, on
comprend que ces dernières ne sont plus soumises à une copie profonde. Généralement, le
programme peut alors fournir une méthode de son crû pour gérer convenablement (plus précisément, comme on le désire) cette copie, qu’elle soit induite par une affectation ou par le
passage en paramètre.
Exercice 11.4 Doter la classe Segment présentée au paragraphe 2, page 235, d’une méthode de copie superficielle et d’une méthode de copie profonde. Pour réaliser cette seconde
méthode, on prévoiera d’adapter la classe Point en la dotant d’une méthode de copie.
5 Une classe « singleton »
N.B. Ce paragraphe peut être ignoré dans un premier temps.
Jusqu’ici, nous avons rencontré des situations dans lesquelles une classe A contenait un attribut de type classe B. Mais il est également possible qu’une classe A renferme un attribut de ce
même type A.
Supposons par exemple qu’on l’on souhaite réaliser une classe nommée Singleton ne permettant d’instancier qu’un seul objet de sa classe. Plus précisément, on souhaite que chaque
tentative d’instanciation, à partir de la seconde, fournisse toujours la référence à un seul et
unique objet. Compte tenu de la manière dont fonctionne le constructeur et du fait qu’il ne
fournit pas de résultat, on voit qu’il n’est pas possible d’opérer cette gestion d’objet unique
dans le constructeur lui-même. Les demandes d’instanciation doivent donc être adressées à
une autre méthode de la classe Singleton que nous nommerons créeInstance et qui
doit :
• instancier un objet lors de son premier appel ;
