(Une méthode est une procédure (ou fonction) particulière parce qu'elle a un paramètre caché, un pointeur vers l'objet)
Inacceptable parce qu'il y a énormément de
duplication
inutile de pointeurs vers les méthodes
Quand une méthode d'une classe C est appelée le compilateur sait de quelle procédure il s'agit?
Pas toujours! dans le cas d'héritage avec possibilité de (re)définir une méthode connue au niveau supérieur, un pointeur qui est (textuellement) un pointeur vers la classe initiale peut être (dynamiquement) un pointeur vers un objet de l'extension. C'est la méthode de l'extension qu'il faut appeler. Et le même code doit marcher dans les deux cas.
Y compris le pointeur implicite qui est le paramètre caché.
Chaque objet contient (dans son premier mot) un pointeur vers un tableau (constant) qui dépend du type de l'objet. Ce tableau contient les pointeurs vers les méthodes valables pour ce type. Le tableau d'une extension contient des pointeurs vers les méthodes de la classe mère sauf quand ces méthodes ont une définition locale dans l'extension.
Dans une extension les nouveaux attributs [méthodes] sont placés après les anciens dans l'enregistrement [tableau des méthodes]
Coût supplémentaire mais pas très important:
espace: un petit tableau pour chaque classe et un pointeur pour chaque
objet
temps: un niveau d'indirection pour chaque appel d'une méthode
(sauf optimisation...)
Mais ce système ne marche toujours pas dans le cas
d'héritage
multiple!
ni pour les méthodes ni pour les champs.
Parce que si une classe C est une extension de A et de B,
un objet de classe C ne peut pas avoir les attributs de A
et ceux de B au début.
inconvénients
L'ordre est: d'abord les nouveaux attributs/méthodes et ensuite ceux hérités.
la section d'un objet contient un pointeur vers la section correspondante du tableau
Un pointeur vers un objet pointe vers la section du type du pointeur
Le tableau contient, pour chaque méthode, l'adresse de son code et un d, qui sert à mettre à jour un pointeur