Bonjour. On va voir ensemble dans cette séquence une
subtilité extrêmement intéressante que vous pouvez
appliquer dans vos programmes, et donc on va revenir sur
l'exemple du programme de dé.
Donc on avait défini, souvenez-vous, dans l'exercice des
dés, donc la classe dés ici qui permettait de définir des
instances de cette classe pour représenter des dés de plusieurs faces.
Et on avait défini une classe DiceHandle, donc une poignée de dés.
On avait implémenté la méthode "+" sur la classe poignée
de dés pour additionner des poignées de dés, et
construire une nouvelle poignée de dés.
Je vous remontre ici le code de cette classe.
On a " DiceHandleNew" ici, on crée une nouvelle poignée
de dés dans laquelle on va ajouter les dés du receveur et
les dés du paramètre, et on va retourner cette poignée de
dés à la fin de la méthode.
Donc maintenant on va voir dans cette séquence la
différence entre écrire dans cette méthode "+",
"DiceHandle new" et écrire "Self class new".
Et pourquoi une technique est meilleure que l'autre.
Je vous montre le problème.
Le problème c'est que si je crée une sous-classe de
"DiceHandle" qui s'appelle "MemoDiceHandle", et que
maintenant je veux additionner des poignées de dés de
type "Memo", donc avec la méthode "+" qui héritait de
"DiceHandle", on voit que le résultat que j'obtiens c'est
une instance de la classe "DiceHandle" et pas une
instance de la classe "MemoDiceHandle".
Donc ça c'est un problème.
En fait, on aimerait quand on additionne des éléments
obtenir le même type d'éléments.
Comment faire pour implémenter ça ?
Solution 1, je vais changer l'implémentation de la
méthode "+" sur la classe "DiceHandle", et on
va juste modifier ici, rajouter cette méthode-là.
Donc, au lieu de fixer la classe que je veux instancier
comme étant "DiceHandle", je vais prévoir une méthode que
j'appelle "HandleClass". Dans "DiceHandle", elle va
retourner la classe "DiceHandle", et dans la sous-classe
"MemoDiceHandle" ça va retourner la classe "MemoDiceHandle".
Juste en redéfinissant cette méthode "HandleClass", ça va
me permettre d'obtenir la bonne instance au moment où j'additionne
des éléments.
On a bien ici, si j'exécute le même sniped de code mais
avec des MemoDiceHandle, une instance de MemoDiceHandle
parce que j'ai redéfini HandleClass, la méthode
HandleClass dans la classe MemoDiceHandle.
Donc on bien une instance de la sous-classe.
Donc on a bien atteint l'objectif qu'on s'était fixé, le
problème c'est qu'il va falloir à chaque fois qu'on
ajoute une sous-classe à DiceHandle, redéfinir cette
méthode HandleClass.
Il ne faut pas oublier de la redéfinir sinon la méthode
"+" ne va jamais retourner l'instance de la bonne classe.
C'est quelque chose qui est un peu contraignant, il faut
toujours redéfinir la méthode, on pourrait faire beaucoup mieux.
Je vous montre la solution 2.
La solution 2 c'est la suivante.
La méthode "+" dans DiceHandle, cette fois on va écrire
directement "SelfClass new".
Je vais demander au receveur courant sa classe et je vais l'instancier.
Et en fait cette classe va toujours retourner la classe du receveur courant.
Si c'est une instance d'une sous-classe, ça va bien
retourner la bonne classe, "MemoDiceHandle" par exemple.
Et on va bien obtenir des instances qui sont du même type
que celui du receveur.
En conclusion, dans cette séquence, vous avez vu que
quand on envoie le message "+" à un "DiceHandle", si on a
fixé dans cette méthode "+" le nom de la classe à
instancier, quelque part on s'interdit la redéfinition,
on s'interdit le fait de créer des sous-classes et que ça
marche toujours en instanciant le bon objet du bon type
d'une des sous-classes potentiellement.
Donc il vaut mieux vraiment utiliser "SelfClass new" pour
instancier directement la classe
en fonction du type courant du receveur.