UE 2I002 (ex LI230) : éléments de programmation par objets

Preview:

Citation preview

UE 2I002 (ex LI230) : éléments de programmation par objets avec Java TD8 - Héritage et liaison dynamique

!!!

Juliana Silva Bernardesjuliana.silva_bernardes@upmc.fr

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

Recommended