Le principe de la liaison dynamique
On considère l'ensemble de classes ci-dessous.
L'objectif est de savoir quelle est la sortie de la méthode main
de la classe QuelleMethode.
Dans la méthode main :
- La variable a est
déclarée de type A.
- Lors de l'instruction 1,
la variable a référence un
objet de type A ; de toute évidence,
la méthode faire utilisée
à l'exécution est la méthode faire
de la classe A.
- Le point important est de comprendre ce qui se passe pour l'instruction 2. À
l'exécution, on obtient niveau B.
- Si le compilateur devait décider de quelle
méthode faire il s'agit, puisque
l'instruction est a.faire();, il regarderait le
type de la variable a, il s'agit de A,
et déciderait donc qu'il s'agit de la méthode faire
de la classe A ; on obtiendrai niveau A. En effet, le compilateur ne peut
pas savoir quel objet sera référencé
par la variable a à
l'exécution (même si on le voit clairement dans
notre petit programme qui est particulièrement
simple) ; le compilateur ne remonte jamais dans l'historique des
instructions, et serait d'ailleurs incapable de le faire dans la
plupart des situations. Le compilateur
se limite à vérifier que la classe A
possède une méthode faire ayant
des paramètres correspondant aux paramètres de
l'appel ; si ce n'était pas le cas, la
compilation des instructions a.faire n'aboutirait
pas.
- La méthode faire
à exécuter est décider à
l'exécution. La machine virtuelle (par qui
passe l'exécution du programme) "regarde" quel est l'objet
référencé par la variable a
; comme il s'agit d'un objet de type B, c'est la
méthode faire de la classe B
qui est utilisée. Le fait que la méthode soit
déterminée à l'exécution
s'exprime par le fait qu'il s'agit d'une liaison
dynamique vers la méthode faire
(le mot dynamique qualifie quelque chose qui est
déterminé à l'exécution, en
opposition au mot statique qui concerne la compilation). Sans ce
principe de la liaison dynamique, l'héritage perdrait
beaucoup d'intérêt, c'est ce que vous
découvrirez avec plus d'expérience.
- Au moment de l'instruction
3, l'objet référencé par a
est de type C ; la classe C
ne redéfinit pas la méthode faire
; la méthode utilisée est alors celle
héritée de B.
class
A {
void faire() {
System.out.println("niveau a");
}
}
class B extends A {
void faire() {
System.out.println("niveau b");
}
}
class C extends B {}
class QuelleMethode {
public static void main(String[] argv) {
A a;
a = new A();
a.faire(); // instruction 1
a = new B();
a.faire(); // instruction 2
a = new C();
a.faire(); // instruction 3
}
}
On obtient à l'exécution, avec notre
programme :
niveau a
niveau b
niveau b
Le fichier
QuelleMethode.java
© Irène
Charon
Télécom ParisTech 2012