|
Notes sur le polymorphisme
Le polymorphisme n'est pas une notion propre a JAVA. JAVA n'est qu'un langage
de programmation parmis d'autres qui implemente la notion de polymorphisme.
Le polymorphisme en deux mots
|
Considerons trois classes A, B et C telles que: C derive de B et B derive de A.
Ce que l'on peut representer par la figure ci dessous:
|
En deux mots: "une instante de C est reconnue comme etant aussi une instance
de B et de A". Par contre une instance de B est reconnue comme etant une instance de A mais
pas de C.
Considerons le programme suivant:
Fichier test.java |
public class test
{
public static void main (String[] atgv)
{
System.out.println("--- Creation d'une instance de la classe <> ---");
b ib = new b();
System.out.println("--- Creation d'une instance de la classe <> ---");
c ic = new c();
System.out.println(" ");
System.out.println("ic instance de c ?: ");
System.out.println(ic instanceof c);
System.out.println("ic instance de b ?: ");
System.out.println(ic instanceof b);
System.out.println("ic instance de a ?: ");
System.out.println(ic instanceof a);
System.out.println(" ");
System.out.println("ib instance de c ?: ");
System.out.println(ib instanceof c);
System.out.println("ib instance de b ?: ");
System.out.println(ib instanceof b);
System.out.println("ib instance de a ?: ");
System.out.println(ib instanceof a);
}
}
class a
{
a()
{
System.out.println("Creation d'une instance de la classe <>.");
}
}
class b extends a
{
b()
{
System.out.println("Creation d'une instance de la classe <>.");
}
}
class c extends b
{
c()
{
System.out.println("Creation d'une instance de la classe <>.");
}
}
|
A l'execution, on obtient:
Considerons le programme suivant:
Fichier test.java |
public class test
{
public static void main (String[] atgv)
{
System.out.println("-- Creation d'une voiture --");
voiture v = new voiture(11);
System.out.println("-- Creation d'une moto --");
moto m = new moto(22);
System.out.println("-- Numero de la voiure :"+ v.Get_Numero());
System.out.println("-- Numero de la moto :"+ m.Get_Numero());
}
}
class vehicule
{
int numero;
vehicule()
{
System.out.println("Creation d'un vehicule");
}
int Get_Numero() { return numero; }
}
class moto extends vehicule
{
moto(int n)
{
System.out.println("Creation d'une mote - numero: " + n);
numero = n;
}
}
class voiture extends vehicule
{
voiture(int n)
{
System.out.println("Creation d'une voiture - numero: " + n);
numero = n;
}
}
|
A l'execution on obtient le resultat suivant:
C:\programmes\java>java test
-- Creation d'une voiture --
Creation d'un vehicule
Creation d'une voiture - numero: 11
-- Creation d'une moto --
Creation d'un vehicule
Creation d'une mote - numero: 22
-- Numero de la voiure :11
-- Numero de la moto :22
|
Remarquer que la fonction Get_Numero() n'est pas definie dans les classes
voiture et moto. Get_Numero est definie dans la classe vehicule.
Dans ces conditions comment se fait il que le compilateur accepte d'appliquer la methode
Get_Numero() a des instances des classes voiture et moto ?
Les classes voiture et moto derivent de la classe vehicule. Par consequent
les handles v (sur voiture) et m (sur moto) contiennent les informations
suivantes:
- v pointe sur une instance de vehicule, et "plus particuliairement" c'est une voiture.
- m pointe sur une instance de vehicule, et "plus particuliairement" c'est une moto.
Lors de l'appel a v.Get_Numero(), v est reconnu en tant que vehicule.
Remarque: Nous aurions pu definir la méhode Get_Numero() dans les classes
voiture et moto. Cela reviendrait a surcharger la methode Get_Numero().
A l'execution le resultat aurait ete le meme. Toutefois cela nous oblige a maintenir
deux versions de la fonction Get_Numero().
Reprenons l'exemple precedent, legerement modifie:
public class test
{
public static void main (String[] atgv)
{
System.out.println("-- Creation d'une voiture --");
voiture v = new voiture(11);
System.out.println("-- Creation d'une moto --");
moto m = new moto(22);
System.out.println("-- Creation d'un vehicule --");
vehicule vv = new vehicule();
System.out.println("-- Numero du vehicule :"+ Get_Numero(vv));
System.out.println("-- Numero de la voiure :"+ Get_Numero(v));
System.out.println("-- Numero de la moto :"+ Get_Numero(m));
}
static int Get_Numero(vehicule vh) { return vh.numero; }
}
class vehicule
{
int numero;
vehicule()
{
System.out.println("Creation d'un vehicule");
}
}
class moto extends vehicule
{
moto(int n)
{
System.out.println("Creation d'une mote - numero: " + n);
numero = n;
}
}
class voiture extends vehicule
{
voiture(int n)
{
System.out.println("Creation d'une voiture - numero: " + n);
numero = n;
}
}
|
A l'execution, nous obtenons:
C:\programmes\java>java test
-- Creation d'une voiture --
Creation d'un vehicule
Creation d'une voiture - numero: 11
-- Creation d'une moto --
Creation d'un vehicule
Creation d'une mote - numero: 22
-- Creation d'un vehicule --
Creation d'un vehicule
-- Numero du vehicule :0
-- Numero de la voiure :11
-- Numero de la moto :22
|
Dans ce cas, lors de l'appel de la methode Get_Numero, les instances
de voiture et de moto sont "sur caster" est vehicule.
Attention !
static int Get_Numero(vehicule vh) { return vh.numero; }
La variable vh est de type vehicule et non voiture
ou moto. Lors de l'appel Get_Numero(v), seule "la partie vehicule"
de v est transmise a la variable vh. On peut dire qu'il y a "perte d'information".
|
L'exemple qui suit provoque une erreur de compillation:
Fichier test.java |
public class test
{
public static void main (String[] atgv)
{
System.out.println("-- Creation d'une voiture --");
voiture v = new voiture(11);
System.out.println("-- Creation d'une moto --");
moto m = new moto(22);
System.out.println("-- Creation d'un vehicule --");
vehicule vv = new vehicule();
System.out.println("-- Numero de la voiure :"+ Get_Numero(v));
System.out.println("-- Numero de la moto :"+ Get_Numero(m));
}
static int Get_Numero(vehicule vh)
{
vh.type(); // provoque une erreur de compilation !
return vh.numero;
}
}
class vehicule
{
int numero;
vehicule()
{
System.out.println("Creation d'un vehicule");
}
}
class moto extends vehicule
{
moto(int n)
{
System.out.println("Creation d'une mote - numero: " + n);
numero = n;
}
void type() { System.out.println(" => Moto"); }
}
class voiture extends vehicule
{
voiture(int n)
{
System.out.println("Creation d'une voiture - numero: " + n);
numero = n;
}
void type() { System.out.println(" => Voiture"); }
}
|
La compilation de ce programme genere l'erreur quivante:
C:\programmes\java>javac test.java
test.java:18: Method type() not found in class vehicule.
vh.type(); // provoque une erreur de compilation !
^
1 error
|
|