Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
UE 2I002 (ex LI230) : éléments de programmation par objets avec Java TD8 - Héritage et liaison dynamique
!!!
Juliana Silva [email protected]
http://www.lcqb.upmc.fr/julianab/teaching/JAVA/
2
‣Transtypage d’objet (Cast)
‣instanceof
‣Méthode equals()
‣Liaison dynamique
‣Contexte de méthode
Sumary
3
Transtypage des types primitifs
‣ Transtypage implicite‣On peut affecter à un champ ou une variable d'un type une expression de type
moins élevé dans la hiérarchie des types.
inta=100;floatb=a;
charshortintfloatdoublelong
4
floata=100;intb=a;
‣ Transtypage explicite‣Mais nous pouvons pas faire le contraire, sans une Transtypage explicite
TestCast.java:7: error: incompatible types: possible lossy conversion from float to int int b = a; ^ 1 error
Transtypage des types primitifs
charshortintfloatdoublelong
5
floata=100; //intb=a; intb=(int)a;
‣ Transtypage explicite
Transtypage des types primitifs
charshortintfloatdoublelong
6
floatb=100.87f;intb=(int)a;System.out.println(b);
‣ Transtypage explicite‣Mais attention on pert en precision
Transtypage des types primitifs
charshortintfloatdoublelong
100Dans le terminal
7
Transtypage d’objet (Cast)
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intx=2;intz=3;publicintgetX(){returnx;}publicintgetZ(){returnz;}}
‣ Transtypage implicite des objets
publicclassTestCast{ publicstaticvoidmain(String[]args){ Aa=newA(); Bb=newB(); a=b; } } Le plus spécifique peut être
attribuer au plus générale
AB
Heritage
8
Transtypage d’objet (Cast)
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intx=2;intz=3;publicintgetX(){returnx;}publicintgetZ(){returnz;}}
publicclassTestCast{ publicstaticvoidmain(String[]args){ Aa=newA(); Bb=newB(); b=a; } }
javac TestCast.java TestCast.java:5: error: incompatible types: A cannot be converted to B b = a; ^ 1 error Juliana
Le plus générale ne peut pas être attribuer au plus spécifique
‣ Transtypage implicite des objets
AB
9
Transtypage d’objet (Cast)
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intx=2;intz=3;publicintgetX(){returnx;}publicintgetZ(){returnz;}}
publicclassTestCast{ publicstaticvoidmain(String[]args){ Aa=newA(); Ab=newB(); b=a; System.out.println(b.getX()); } }
$ javac *.java$ java TestCast$0
‣ Transtypage implicite des objets
AB
La methode getX() existe dans la class A, pas d’error de compilation
10
Transtypage d’objet (Cast)
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intw=2;intz=3;publicintgetW(){returnw;}publicintgetZ(){returnz;}}
publicclassTestCast{ publicstaticvoidmain(String[]args){ Aa=newA(); Ab=newB(); b=a; System.out.println(b.getY()); } }
$ javac *.java$ java TestCast
$ 1
‣ Transtypage implicite des objets
AB
La methode getY() existe dans la class A, pas d’error de compilation
11
Transtypage d’objet (Cast)
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intw=2;intz=3;publicintgetW(){returnw;}publicintgetZ(){returnz;}}
publicclassTestCast{ publicstaticvoidmain(String[]args){ Aa=newA(); Ab=newB(); b=a; System.out.println(b.getZ()); } }javac TestCast.java TestCast.java:6: error: cannot find symbol System.out.println(b.getZ()); ^ symbol: method getZ() location: variable b of type A 1 error
‣ Transtypage implicite des objets
La methode getZ() n'existe pas dans la class A, d’error de compilation
AB
12
Transtypage d’objet (Cast)
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intw=2;intz=3;publicintgetW(){returnw;}publicintgetZ(){returnz;}}publicclassCextendsB{inte=2;publicintgetE(){returne;}}
publicclassTestCast{ publicstaticvoidmain(String[]args){ Ac=newC(); Bb=c; System.out.println(b.getX()); } }javac TestCast.java TestCast.java:4: error: incompatible types: A cannot be converted to B B b = c; ^ 1 error !
‣ Transtypage implicite des objets
ABC
ABC
13
Transtypage d’objet (Cast)
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intw=2;intz=3;publicintgetW(){returnw;}publicintgetZ(){returnz;}}publicclassCextendsB{inte=2;publicintgetE(){returne;}}
publicclassTestCast{ publicstaticvoidmain(String[]args){ Ac=newC(); Bb=(B)c; System.out.print(b.getX()); System.out.println(b.getZ()); } }
‣ Transtypage explicite des objets
$ javac TestCast.java$ java TestCast$ 0 4
ABC
14
Transtypage d’objet (Cast)
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intw=2;intz=3;publicintgetW(){returnw;}publicintgetZ(){returnz;}}publicclassCextendsB{inte=2;publicintgetE(){returne;}}
publicclassTestCast{ publicstaticvoidmain(String[]args){ Ac=newC(); Bb=(B)c; Cc2=(C)c; System.out.println(b.getX()); System.out.println(c2.getE()); } }
$ javac *.java$ java TestCast$ 0 2
‣ Transtypage explicite des objets
ABC
15
Instanceof
16
Instanceof
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intw=2;intz=3;publicintgetW(){returnw;}publicintgetZ(){returnz;}}publicclassCextendsA{inte=2;publicintgetE(){returne;}}
publicclassTestInstanceOf{ publicstaticvoidmain(String[]args){ A[]tab=newA[10]; for(inti=0;i<tab.length;i++){ if(Math.random()<0.3){ tab[i]=newB(); }else{ tab[i]=newC(); } } } }
‣On veut créer un tableau pour mettre 30% d'objets du type B et 70% du type C
17
Instanceof
publicclassTestInstanceOf{ publicstaticvoidmain(String[]args){ A[]tab=newA[10]; for(inti=0;i<tab.length;i++){ if(Math.random()<0.3) tab[i]=newB(); else tab[i]=newC(); }! for(inti=0;i<tab.length;i++){ Aa=tab[i]; if(ainstanceofB) System.out.println(a.getW()); elseif(ainstanceofC) System.out.println(a.getE()); } } }
‣ Pour les objets du type B, on va imprimer la sortie de la méthode getW(), pour les objets du type C, on va imprimer la sortie de la méthode getE()
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intw=5;intz=3;publicintgetW(){returnw;}publicintgetZ(){returnz;}}publicclassCextendsA{inte=2;publicintgetE(){returne;}}
$ javac *.java TestCast.java:15: error: cannot find symbol System.out.println(a.getW()); ^ symbol: method getW() location: variable a of type A TestCast.java:17: error: cannot find symbol System.out.println(a.getE()); ^ symbol: method getE() location: variable a of type A 2 errors
18
Instanceof
publicclassTestInstanceOf{ publicstaticvoidmain(String[]args){ A[]tab=newA[10]; for(inti=0;i<tab.length;i++){ if(Math.random()<0.3) tab[i]=newB(); else tab[i]=newC(); } for(inti=0;i<tab.length;i++){ Aa=tab[i]; if(ainstanceofB){ Bb=(B)a; System.out.println(b.getW()); } elseif(ainstanceofC){ Cc=(C)a; System.out.println(c.getE()); } } }}
‣ Pour les objets du type B, on va imprimer la sortie de la méthode getW(), pour les objets du type C, on va imprimer la sortie de la méthode getE()
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intw=5;intz=3;publicintgetW(){returnw;}publicintgetZ(){returnz;}}publicclassCextendsA{inte=2;publicintgetE(){returne;}}
19
Instanceof
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intw=5;intz=3;publicintgetW(){returnw;}publicintgetZ(){returnz;}}publicclassCextendsA{inte=2;publicintgetE(){returne;}}
publicclassTestInstanceOf{ publicstaticvoidmain(String[]args){ A[]tab=newA[10]; for(inti=0;i<tab.length;i++){ if(Math.random()<0.3) tab[i]=newB(); else tab[i]=newC(); }! for(inti=0;i<tab.length;i++){ Aa=tab[i]; if(ainstanceofB) System.out.println(((B)a).getW()); elseif(ainstanceofC) System.out.println(((C)a).getE()); } }
‣ Pour les objets du type B, on va imprimer la sortie de la méthode getW(), pour les objets du type C, on va imprimer la sortie de la méthode getE()
20
Méthode equals()
21
Méthode equals()
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intw=5;intz=3;publicintgetW(){returnw;}publicintgetZ(){returnz;}}publicclassCextendsA{inte=2;publicintgetE(){returne;}}
publicclassTestInstanceOf{ publicstaticvoidmain(String[]args){ Cc1=newC(); System.out.print(c1.getE()); Cc2=newC(); System.out.println(c2.getE()); if(c1==c2) System.out.println(“égaux"); else System.out.println(“différents”); }}
‣Comment comparer deux objets?
$ javac *.java$ java TestCast$ 2 2$ différents
22
Méthode equals()
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intw=5;intz=3;publicintgetW(){returnw;}publicintgetZ(){returnz;}}publicclassCextendsA{inte=2;publicintgetE(){returne;}}
publicclassTestInstanceOf{ publicstaticvoidmain(String[]args){ Cc1=newC(); System.out.print(c1.getE()); Cc2=newC(); System.out.println(c2.getE()); if(c1.equals(c2)) System.out.println(“égaux"); else System.out.println(“différents”); }}
‣Comment comparer deux objets?
$ javac *.java$ java TestCast$ 2 2$ différents
La méthode equals de la class object verifier si les pointeur des objets sont égaux.
23
Méthode equals()
publicclassA{privateintx=0;privateinty=1;publicintgetX(){returnx;}publicintgetY(){returny;}}publicclassBextendsA{intw=5;intz=3;publicintgetW(){returnw;}publicintgetZ(){returnz;}}publicclassCextendsA{inte=2;publicintgetE(){returne;}publicbooleanequals(Cc){ return(e==c.e);}}
publicclassTestInstanceOf{ publicstaticvoidmain(String[]args){ Cc1=newC(); System.out.print(c1.getE()); Cc2=newC(); System.out.println(c2.getE()); if(c1.equals(c2)) System.out.println(“égaux"); else System.out.println(“différents”); }}
‣Comment comparer deux objets?
$ javac *.java$ java TestCast$ 2 2$ égaux
On doit redefinir la method equals.
24
Liaison dynamique
25
Liaison dynamique
publicclassA{publicvoidfaire(){System.out.println("niveaua");}}!!publicclassBextendsA{publicvoidfaire(){ System.out.println("niveaub"); }}!publicclassCextendsB{}
publicclassQuelleMethode{publicstaticvoidmain(String[]argv){ Aa; a=newA(); a.faire(); }}
$ javac *.java$ java QuelleMethode$ niveau a
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
26
publicclassA{publicvoidfaire(){System.out.println("niveaua");}}!!publicclassBextendsA{publicvoidfaire(){ System.out.println("niveaub"); }}!publicclassCextendsB{}
publicclassQuelleMethode{publicstaticvoidmain(String[]argv){ Aa; a=newA(); a.faire(); a=newB(); a.faire();}}
$ javac *.java
Le compilateur regarde 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.
Liaison dynamique
27
publicclassA{publicvoidfaire(){System.out.println("niveaua");}}!!publicclassBextendsA{publicvoidfaire(){ System.out.println("niveaub"); }}!publicclassCextendsB{}
publicclassQuelleMethode{publicstaticvoidmain(String[]argv){ Aa; a=newA(); a.faire(); a=newB(); a.faire();}}
$ javac *.java
Le compilateur ne peut pas savoir quel objet sera référencé par la variable a à l’exécution.Le compilateur ne remonte jamais dans l'historique des instructions
Liaison dynamique
28
publicclassA{publicvoidfaire(){System.out.println("niveaua");}}!!publicclassBextendsA{publicvoidfaire(){ System.out.println("niveaub"); }}!publicclassCextendsB{}
publicclassQuelleMethode{publicstaticvoidmain(String[]argv){ Aa; a=newA(); a.faire(); a=newB(); a.faire();}}
$ javac *.java
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
Liaison dynamique
29
publicclassA{publicvoidfaire(){System.out.println("niveaua");}}!!publicclassBextendsA{publicvoidfaire(){ System.out.println("niveaub"); }}!publicclassCextendsB{}
publicclassQuelleMethode{publicstaticvoidmain(String[]argv){ Aa; a=newA(); a.faire(); a=newB(); a.faire();}}
La méthode faire à exécuter est décider à l’exécution. 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
Liaison dynamique
$ javac *.java$ java QuelleMethode$ niveau a$ niveau b
30
publicclassA{publicvoidfaire(){System.out.println("niveaua");}}!!publicclassBextendsA{publicvoidfaire(){ System.out.println("niveaub"); }}!publicclassCextendsB{}
publicclassQuelleMethode{publicstaticvoidmain(String[]argv){ Aa; a=newA(); a.faire(); a=newB(); a.faire(); a=newC(); a.faire();}}
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.
Liaison dynamique
$ javac *.java$ java QuelleMethode$ niveau a$ niveau b$ niveau b
31
Contexte de méthode
32
Contexte de méthode
publicclassA{privateintx=0;publicintj(){returnx;}publicintk(){returnx;}}publicclassBextendsA{intx=5;publicintj(){returnx;}publicintu(){returnx;}}
publicclassTest{publicstaticvoidmain(String[]argv){ Aa=newA(); Bb=newB(); System.out.print(a.j()); !!!!!!!!!! }}
$ 0System.out.print(a.k()); $ 0System.out.print(b.j()); $ 5System.out.print(b.u()); $ 5a=bSystem.out.print(a.j()); $ 5System.out.print(a.k()); $ 0System.out.print(b.j()); $ 5System.out.print(b.u()); $ 5