Bonjour. Dans ce cours on va aborder un point qui n'est
pas souvent abordé dans les cours de Pharo qui sont:
Comment est-ce qu'on définit des objets de taille variable?
Si on regarde, on voit qu'on utilise déjà des objets de taille variable.
Quand je veux créer un tableau avec cette expression-là,
je vais créer un tableau ayant 10 éléments.
Là, ils sont tous mis à 1 000, mais avec cette même
expression-là, je vais créer un tableau qui aura 5
éléments. Donc on voit que la classe "Tableaux" crée des
instances qui sont de taille variable.
Et pour le moment, on ne vous a pas expliqué comment vous pouviez faire.
Si je vous donnais ça comme exercice, vous ne sauriez pas le faire.
Donc, ce qu'on va voir dans ce cours, rapidement, c'est
comment on définit des classes dont les instances ont des
tailles variables, comment on instancie de tels objets et
comment on accède à ces tailles variables.
Commençons par le premier point.
En fait c'est très simple.
On va utiliser le message "variableSubclass" au lieu du
message "subclass" dans la définition de classe.
Là, j'ai copié la définition de la classe "Tableaux".
Vous voyez que j'utilise "variableSubclass",
"instanceVariableNames", et caetera., pour créer ma
classe. Alors que normalement, quand vous avez défini la
classe "Counter" ou la classe "D", de toute façon
vous n'aviez utilisé que "subclass".
Donc avec cette définition-là, les instances que vous
allez créer ont des tailles variables.
On va prendre un exemple débile: imaginons qu'on veuille
faire un point un peu étrange avec 2 variables d'instance
X et Y comme un point et une variable, une zone variable,
on mettrait cette définition-là. Qu'est-ce que ça crée?
Ça créerai des objets qui ont cet aspect-là, en fait.
Ce qui veut dire que j'aurais une valeur pour X, une
valeur pour Y, et une zone variable par instance.
Je pourrais avoir une autre instance qui a aussi X, Y,
avec 10 ici, puis 20 là, et là 100 et là 200 par
exemple, et là avec une autre taille variable où je peux
mettre différents objets.
Donc ce qu'on voit, c'est que les instances d'une classe
qui permet d'avoir des instances de taille variable ont
une zone indexée, qui vient s'ajouter après les variables
d'instance qui sont nommées, comme X Y.
Et elle est implicite et il n'y en a qu'une par classe
pour des problèmes d'implémentation, sinon on ne saurait
pas comment ça grandit. Donc voilà, vous avez vu comment
on crée des classes dont les instances ont une taille variable.
Maintenant, comment on les instancie, on l'a déjà vu tout
au début du cours mais on va regarder, et comment on
accède à cette taille variable.
En fait, on les instancie en utilisant le message "New:".
Ce qui est important c'est le message "New:".
On a vu ça dans le cours sur les collections mais c'est bien de le rappeler.
Là ça nous donne: "OK, je veux créer un objet de taille
variable et la taille variable de cet objet est spécifiée
par la valeur max qui est donnée ici".
Donc là, je crée un objet, un tableau, qui aura 4 éléments.
Comment je vais accéder à cette taille variable?
Je vais accéder avec les messages "At" et "at put" que
vous avez vus sur les tableaux. Et ça, ça va marcher pour
tous les objets qui ont une taille variable.
Donc là, si je mets "At 2", ici je vais mettre "Lulu".
Si je regarde et que j'accède à la valeur 1, ça va me
rendre 1 000, c'est normal. Et si je regarde quelle est
la valeur 2, ça me donnera "Lulu".
Donc, en fait, il y a un mapping entre les tableaux et
les objets à taille variable en utilisant "at put" et
"New" parce que ce protocole-là, d'API, va fonctionner
pour les Array et pour tous les objets dont on voudrait
qu'ils aient une taille variable, plus "Variable Size".
Finalement, je ne vous ai pas appris grand-chose dans ce
cours, je vous ai juste montré comment on définissait la
classe "Array" et comment ça se généralise à d'autres
objets, parce que vous connaissiez déjà le protocole.
Donc finalement, si on regarde dans Pharo, on a des
objets ou des classes qui ont ce qu'on appelle des formes différentes.
On va avoir des classes qui n'ont que des variables d'instance
nommées, comme le Counter avec 40 ou la classe D avec le
nombre de faces. Après, on va avoir des classes qui ont
seulement une zone variable ou indexée, comme la classe "Array".
Et puis après, on va voir les autres qui peuvent être un mélange des deux.
Donc là on a quelques contraintes, on peut faire ça,mais
c'est un petit peu plus subtil.
Ça veut dire qu'on peut maintenant décider quel est le
type de classe variable. Là, je ne veux aller dans les
détails je veux juste vous donner l'intention.
Je peux dire que la classe, la partie variable, va être
juste des pointeurs sur des objets, ou des bytes
ou des words. On a besoin de ça parce que parfois, pour s'interfacer
avec le monde extérieur, on a besoin de pouvoir spécifier.
Moi, je veux une taille, et je veux dans cette taille,
mettre des pointeurs sur des objets qui ont une certaine forme.
Cette partie est vraiment avancée, mais c'est juste pour vous montrer.
Donc vous, souvent, vous allez rester dans ce monde-là, avec subclass.
De temps en temps, vous allez utiliser variableSubclass.
Et par exemple, Bitmap, qui est l'objet qui représente l'écran,
est vraiment un objet qui a une zone variable qui sont
des Word. C'était juste pour vous dire que ça existe.
Le système, comme je vous l'ai dit, est un système
réflexif, on peut lui poser des questions.
Vous pouvez donc très bien demander, en utilisant ces
méthodes-là, si c'est une taille fixe, si c'est une
taille variable, si ce sont des pointeurs, si ce sont
plutôt des bytes qui sont stockés, et caetera.
Donc on a toute l'API pour pouvoir demander de quelle
sorte sont les classes. C'est comme ça qu'on a fait cette
liste, en faisant des queries dans le système.
Maintenant, il y a une contrainte: les classes définies
en utilisant subclass peuvent avoir n'importe quelle sorte de sous-classe.
Ça veut dire que si j'ai des points avec X Y, je vais
pouvoir mettre une sous-classe qui va être Z, ou une
sous-classe qui va être X Y plus une taille variable.
Quand vous voulez faire une sous-classe d'une classe qui
est déjà une variable, vous pouvez utiliser exclusivement
des classes qui sont variables, c'est comme ça.
Le système qui construit les classes va vérifier et dire
"Non, c'est incompatible, je ne peux pas le faire".
Pourquoi? Parce que lui a besoin de savoir qu'il n'y a
qu'une zone et traiter les contraintes.
Donc, de toute façon, le système vous dira que ce n'est
pas possible de le créer. C'était juste pour vous dire que ça existe.
Donc, ce que vous devez savoir finalement maintenant, c'est
comment on définit des classes dont les instances ont une
taille variable, comment on les instancie, avec New:, et
comment on y accède avec les protocoles qui sont les
protocoles que vous avez vus sur les tableaux.