• Aucun résultat trouvé

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

N/A
N/A
Protected

Academic year: 2022

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

Copied!
32
0
0

Texte intégral

(1)

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

!!

!

Juliana Silva Bernardes

[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.

int a = 100;

float b = a;

char short int

float

double

long

(4)

float a = 100;

int b = 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

char short int

float

double

long

(5)

float a = 100;

//int b = a;

int b = (int)a;

‣ Transtypage explicite

Transtypage des types primitifs

char short int

float

double

long

(6)

float b = 100.87f;

int b = (int)a;

System.out.println(b);

‣ Transtypage explicite

‣ Mais attention on pert en precision

Transtypage des types primitifs

char short int

float double long

100

Dans le terminal

(7)

Transtypage d’objet (Cast)

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int x = 2;

int z = 3;

public int getX(){return x;}

public int getZ(){return z;}

}

‣ Transtypage implicite des objets

public class TestCast {

public static void main(String [] args){

A a = new A();

B b = new B();

a = b;

}

} Le plus spécifique peut être attribuer au plus générale

A

B

(8)

Transtypage d’objet (Cast)

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int x = 2;

int z = 3;

public int getX(){return x;}

public int getZ(){return z;}

}

public class TestCast {

public static void main(String [] args){

A a = new A();

B b = new B();

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

A

B

(9)

Transtypage d’objet (Cast)

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int x = 2;

int z = 3;

public int getX(){return x;}

public int getZ(){return z;}

}

public class TestCast {

public static void main(String [] args){

A a = new A();

A b = new B();

b = a;

System.out.println(b.getX());

} }

$ javac *.java

$ java TestCast

$0

‣ Transtypage implicite des objets

A B

La methode getX() existe dans la class A, pas d’error de compilation

(10)

Transtypage d’objet (Cast)

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int w = 2;

int z = 3;

public int getW(){return w;}

public int getZ(){return z;}

}

public class TestCast {

public static void main(String [] args){

A a = new A();

A b = new B();

b = a;

System.out.println(b.getY());

} }

$ javac *.java

$ java TestCast

$ 1

‣ Transtypage implicite des objets

A B

La methode getY() existe dans la class A, pas d’error de compilation

(11)

Transtypage d’objet (Cast)

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int w = 2;

int z = 3;

public int getW(){return w;}

public int getZ(){return z;}

}

public class TestCast {

public static void main(String [] args){

A a = new A();

A b = new B();

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

A

B

(12)

Transtypage d’objet (Cast)

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int w = 2;

int z = 3;

public int getW(){return w;}

public int getZ(){return z;}

}

public class C extends B { int e = 2;

public int getE(){return e;}

}

public class TestCast {

public static void main(String [] args){

A c = new C();

B b = 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

A B C

A

B

C

(13)

Transtypage d’objet (Cast)

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int w = 2;

int z = 3;

public int getW(){return w;}

public int getZ(){return z;}

}

public class C extends B { int e = 2;

public int getE(){return e;}

}

public class TestCast {

public static void main(String [] args){

A c = new C();

B b = (B)c;

System.out.print(b.getX());

System.out.println(b.getZ());

} }

‣ Transtypage explicite des objets

$ javac TestCast.java

$ java TestCast

$ 0 4

A

(14)

Transtypage d’objet (Cast)

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int w = 2;

int z = 3;

public int getW(){return w;}

public int getZ(){return z;}

}

public class C extends B { int e = 2;

public int getE(){return e;}

}

public class TestCast {

public static void main(String [] args){

A c = new C();

B b = (B)c;

C c2 = (C)c;

System.out.println(b.getX());

System.out.println(c2.getE());

} }

$ javac *.java

$ java TestCast

$ 0 2

‣ Transtypage explicite des objets

A

B

C

(15)

Instanceof

(16)

Instanceof

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int w = 2;

int z = 3;

public int getW(){return w;}

public int getZ(){return z;}

}

public class C extends A { int e = 2;

public int getE(){return e;}

}

public class TestInstanceOf {

public static void main(String [] args){

A [] tab = new A[10];

for (int i =0; i<tab.length; i++){

if (Math.random() < 0.3){

tab[i] = new B();

}else{

tab[i] = new C();

} }

} }

‣ On veut créer un tableau pour mettre 30% d'objets du type B et 70% du type C

(17)

Instanceof

public class TestInstanceOf {

public static void main(String [] args){

A [] tab = new A[10];

for (int i =0; i<tab.length; i++){

if (Math.random() < 0.3) tab[i] = new B();

else

tab[i] = new C();

}

!

for (int i =0; i<tab.length; i++){

A a = tab[i];

if (a instanceof B)

System.out.println(a.getW());

else if (a instanceof C)

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()

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int w = 5;

int z = 3;

public int getW(){return w;}

public int getZ(){return z;}

}

public class C extends A { int e = 2;

public int getE(){return e;}

}

$ 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

(18)

Instanceof

public class TestInstanceOf {

public static void main(String [] args){

A [] tab = new A[10];

for (int i =0; i<tab.length; i++){

if (Math.random() < 0.3) tab[i] = new B();

else

tab[i] = new C();

}

for (int i =0; i<tab.length; i++){

A a = tab[i];

if (a instanceof B){

B b = (B) a;

System.out.println(b.getW());

}

else if (a instanceof C){

C c = (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()

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int w = 5;

int z = 3;

public int getW(){return w;}

public int getZ(){return z;}

}

public class C extends A { int e = 2;

public int getE(){return e;}

}

(19)

Instanceof

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int w = 5;

int z = 3;

public int getW(){return w;}

public int getZ(){return z;}

}

public class C extends A { int e = 2;

public int getE(){return e;}

}

public class TestInstanceOf {

public static void main(String [] args){

A [] tab = new A[10];

for (int i =0; i<tab.length; i++){

if (Math.random() < 0.3) tab[i] = new B();

else

tab[i] = new C();

}

!

for (int i =0; i<tab.length; i++){

A a = tab[i];

if (a instanceof B)

System.out.println(((B)a).getW());

else if (a instanceof C)

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()

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int w = 5;

int z = 3;

public int getW(){return w;}

public int getZ(){return z;}

}

public class C extends A { int e = 2;

public int getE(){return e;}

}

public class TestInstanceOf {

public static void main(String [] args){

C c1 = new C();

System.out.print(c1.getE());

C c2 = new C();

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

(22)

Méthode equals()

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int w = 5;

int z = 3;

public int getW(){return w;}

public int getZ(){return z;}

}

public class C extends A { int e = 2;

public int getE(){return e;}

}

public class TestInstanceOf {

public static void main(String [] args){

C c1 = new C();

System.out.print(c1.getE());

C c2 = new C();

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()

public class A {

private int x = 0;

private int y = 1;

public int getX(){return x;}

public int getY(){return y;}

}

public class B extends A { int w = 5;

int z = 3;

public int getW(){return w;}

public int getZ(){return z;}

}

public class C extends A { int e = 2;

public int getE(){return e;}

public boolean equals(C c){

return (e == c.e);

} }

public class TestInstanceOf {

public static void main(String [] args){

C c1 = new C();

System.out.print(c1.getE());

C c2 = new C();

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

(24)

Liaison dynamique

(25)

Liaison dynamique

public class A{

public void faire() {

System.out.println("niveau a");

} }

!

!

public class B extends A { public void faire() {

System.out.println("niveau b");

} }

!

public class C extends B {}

public class QuelleMethode {

public static void main(String[] argv) { A a;

a = new A();

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)

public class A{

public void faire() {

System.out.println("niveau a");

} }

!

!

public class B extends A { public void faire() {

System.out.println("niveau b");

} }

!

public class C extends B {}

public class QuelleMethode {

public static void main(String[] argv) { A a;

a = new A();

a.faire();

a = new B();

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)

public class A{

public void faire() {

System.out.println("niveau a");

} }

!

!

public class B extends A { public void faire() {

System.out.println("niveau b");

} }

!

public class C extends B {}

public class QuelleMethode {

public static void main(String[] argv) { A a;

a = new A();

a.faire();

a = new B();

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)

public class A{

public void faire() {

System.out.println("niveau a");

} }

!

!

public class B extends A { public void faire() {

System.out.println("niveau b");

} }

!

public class C extends B {}

public class QuelleMethode {

public static void main(String[] argv) { A a;

a = new A();

a.faire();

a = new B();

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)

public class A{

public void faire() {

System.out.println("niveau a");

} }

!

!

public class B extends A { public void faire() {

System.out.println("niveau b");

} }

!

public class C extends B {}

public class QuelleMethode {

public static void main(String[] argv) { A a;

a = new A();

a.faire();

a = new B();

a.faire();

} }

La méthode faire à exécuter est décider à l’exécution.

Liaison dynamique

$ javac *.java

$ java QuelleMethode

$ niveau a

$ niveau b

(30)

public class A{

public void faire() {

System.out.println("niveau a");

} }

!

!

public class B extends A { public void faire() {

System.out.println("niveau b");

} }

!

public class C extends B {}

public class QuelleMethode {

public static void main(String[] argv) { A a;

a = new A();

a.faire();

a = new B();

a.faire();

a = new C();

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

public class A {

private int x = 0;

public int j(){return x;}

public int k(){return x;}

}

public class B extends A { int x = 5;

public int j(){return x;}

public int u(){return x;}

}

public class Test {

public static void main(String[] argv) { A a = new A();

B b = new B();

System.out.print(a.j());

!

!

!

!

!

!

!

!

!

!

} }

$ 0

System.out.print(a.k());

$ 0

System.out.print(b.j());

$ 5

System.out.print(b.u());

$ 5

a=b

System.out.print(a.j());

$ 5

System.out.print(a.k());

$ 0

System.out.print(b.j());

$ 5

System.out.print(b.u());

$ 5

Références

Documents relatifs

On ne peut pas utiliser l’opérateur « point » (.) sur les variables de la classe Chien ailleurs que dans la classe Chien

UE 2I002 (ex LI230) : éléments de programmation par objets avec Java!. TD4 - Composition,

‣ Un tableau est une structure de données contenant un groupe d'éléments tous du même type. ‣ Le type des éléments peut être un type primitif ou

‣ boolean, byte, short, char, int, long, float et double, sont associées des classes Boolean, Byte, Short, Character, Integer, Long, Float et Double. ‣ Ces classes ont des

6OF EFT QSPQSJÏUÏT JOEVJUFT QBS MF QPMZNPSQIJTNF FTU RVF MJOUFSQSÏUFVS +BWB FTU DBQBCMF EF USPVWFS MF USBJUFNFOU Ë FČFDUVFS MPST EF MBQQFM EVOF NÏUIPEF TVS VO PCKFU &#34;JOTJ

-F DPODFQU EF DMBTTF BCTUSBJUF TF TJUVF FOUSF DFMVJ EF DMBTTF FU DFMVJ EJOUFSGBDF $FTU VOF DMBTTF RVPO OF QFVU QBT EJSFDUFNFOU JOTUBODJFS DBS DFSUBJOFT EF TFT NÏUIPEFT OF TPOU

Depuis le début de l’année, nous utilisons systématiquement la méthode main avec un paramètre de type String[], c’est à dire un tableau de chaînes de caractères. Ce

‣ La classe Error représente une erreur grave intervenue dans la machine virtuelle