Vous êtes sur la page 1sur 11

AU.

: 2019/2020/Session d’Automne
Filière : LST Génie Logiciel, S5
Module : I511
Professeur : M.OUALLA

TP N°4 : Héritage - Solutions


Exercice 1:
L’instruction : A a = new A(3); fait appel à un constructeur inexistant. Toutes les autres
lignes utilisent des méthodes héritées de la classe Object ce qui est toujours possible.

Exercice 2:

Le constructeur B() n’appelle, explicitement, ni this(), ni super(). Donc, par convention, le


constructeur de la super-classe A est appelé (implicitement) avant de procéder. Ceci donne b1.x
= 6.
Le constructeur B(2003) appelle le constructeur précédent avec le this(), ce qui donne b2.x=6,
ensuite on y ajoute 2003, ce qui donne finalement b2.x=2009.
Le constructeur B(”Bonjour”) appelle le constructeur de la super-classe A avec le super(). Ceci
donne b3.x=5. Ensuite on le décrémente et on aura finalement b3.x=4.
Donc le résultat final sera : 6 et 2009 et encore 4
Exercice 3:

Etant donnée que la classe Triangle étend la classe Figure:


1) Figure f1 =new Figure(); Triangle tr= (Triangle)f1; Figure f2=(Figure)tr;
La compilation se fait sans erreurs, mais à l’exécution le downcasting explicite de la deuxième
instruction produit une ClassCastException, comme une simple Figure référée par f1 n’est pas
un Triangle, autrement, le type dynamique da la variable f1 qui est Figure ne peut pas être
converti en type Triangle qui est le type de la variable tr.
2) Triangle tr1= new Triangle(); Figure f = tr1; Triangle tr2=(Triangle)f;
Ici tout va bien : l’objet construit par la première instruction est un Triangle, la deuxième
instruction est un upcasting implicite, la troisième instruction est un downcasting explicite qui
se déroule bien car le type dynamique de f qui est Triangle peut être attribué à tr2 de type
statique Triangle.

3) Triangle tr1= new Triangle(); Object o = (Object)tr1; Triangle tr2=o ;


La troisième instruction est un downcasting implicite qui mène à une erreur de compilation.

4) Figure f1 =new Figure(); Triangle tr= (Triangle)f1; Figure f2=tr ;


La compilation se fait sans erreurs, mais à l’exécution le downcasting explicite de la deuxième
instruction produit une ClassCastException, comme une simple Figure référée par f1 n’est pas
un Triangle.

1/11
AU. : 2019/2020/Session d’Automne
Filière : LST Génie Logiciel, S5
Module : I511
Professeur : M.OUALLA

Exercice 4:

La classe A, définit trois méthodes :


- Une méthode de classe public g(int) qui accepte un argument de type int et qui ne
retourne rien.
- Une méthode public f(float) qui accepte un argument de type float et qui ne retourne
rien.
- Une méthode public f(int) qui surcharge la méthode f(float) en lui passant comme
paramètre une variable de type float.
- Le code de cette classe ne contient aucune erreur.
La classe B qui hérite de la classe A, définit les méthodes suivantes :
- Une méthode de classe privée g() qui n’accepte aucun argument et qui retourne une
valeur de type double. On peut remarquer que cette méthode surcharge la méthode g(int)
de la classe mère, les conditions de surcharge sont bien satisfaites (nombre d’arguments
et type de retour différents), aussi dans cette méthode, on a diminué sa visibilité : public
vers private, et ceci n'affecte pas l’opération de surcharge. En effet, la déclaration de
cette méthode est correcte :
private static double g() {return 0.0;} //CORRECT
- Une méthode privée f(float) qui redéfinit la méthode f(float) de la classe mère, puisque
les deux méthodes possèdent la même signature (Type de retour, nom, arguments).
Mais, dans cette méthode, on a diminué sa visibilité : public vers private, et ceci affecte
l’opération de redéfinition (Dans la redéfinition d’une méthode, on ne peut pas diminuer
la visibilité en revanche, on peut l’augmenter, donc :
// ERREUR: Redéfinition de f(float) de A
mais avec diminution de visibilité
private void f (float n) {}

- Une méthode public f(int) qui possède les mêmes paramètres que f(int) de la classe mère
mais avec le type de retour différent, donc la définition de cette méthode ne respecte pas
ni les règles de redéfinition ni celles de surcharge ce qui génère une erreur de
compilation :

// ERREUR: ici on n'a ni redéfini ni surchargé la méthode f(),


on a seulement changé le type de retour.
public float f(int n) {return 0.0f;}

Exercice 5:
a.f(n) ;
Appel de f(int) de A (surcharge de f dans A)
a.f(x) ;
Appel de f(float) de A (surcharge de f dans A)
a.f(l) ;

2/11
AU. : 2019/2020/Session d’Automne
Filière : LST Génie Logiciel, S5
Module : I511
Professeur : M.OUALLA

Appel de f(float) de A car long<float(surcharge de f dans A)


a.f(y) ;
ERREUR DE COMPILATION: f(double) non définie dans A
a.f(m) ;
Appel de f(int) de A (byte < int : surcharge de f dans A).
b.f(n) ;
Appel de f(int) de B (redéfinition de f(int) de A)
b.f(x) ;
Appel de f(float) de A (f(float) non définie dans B, donc on fait appel à f(float) de A :
surcharge de f dans A)
b.f(l) ;
Appel de f(long) de B (surcharge de f dans B et A)
b.f(y) ;
ERREUR DE COMPILATION: f(double) non définie, ni dans A ni dans B.
b.f(m) ;
Appel de f(int) de B (byte < int : surcharge de f dans B et A).
a.g() ;
Appel de g() de A.
b.g() ;
Appel de g() de A (g() n’est pas définie dans B, donc on fait appel à g() de la classe A).
b.g(m) ;
Appel de g(int) de B (byte < int : surcharge de g de A).
a.f(a.g());
Appel de g() puis f(float) de A.
b.f(b.f(l));
ERREUR DE COMPILATION: appel de f(long) de B qui retourne un double, ensuite appel
de f(double) de B qui n'est pas définie.

Exercice 6:
B b=new B() ;
Cette instruction crée un objet b de type B.
A a =b ;

La variable objet a référence le même objet de type B que la variable b.

3/11
AU. : 2019/2020/Session d’Automne
Filière : LST Génie Logiciel, S5
Module : I511
Professeur : M.OUALLA

On constate que le type statique de a est A et son type dynamique est B.


System.out.println(a.f(2)*a.g(3));

a.f(2):
La méthode f() est statique donc on ne peut pas la redéfinir, càd que son appel sera effectué
en se basant sur le type statique et pas sur le type dynamique.
NB. L’appel des méthodes d’instances, en revanche, se base sur le type dynamique.
Alors a.f(2) fait appel à la méthode f() de la classe A qui va retourner la valeur 7 (2+5).
a.g(3):
La méthode g() est une méthode d’instance donc son appel sera basé sur le type dynamique
de l’objet appelant. Donc, a.g(3) fait appel à la méthode g() redéfinie dans la classe B qui va
retourner la valeur 11 (3+8).
a.f(2)*a.g(3):

Le résultat final sera donc : 7 * 11 = 77.

Exercice 7:
Le diagramme de classe de cette application est le suivant :

Point Forme
- abscisse : double # p : Point
- ordonnee : double
+ <<Forme>>(Point p)
+ <<Point>>() + deplacer(double dx, double dy): void
+ <<Point>>( double abscisse, double 1 n + surface() : double
ordonnee) + perimetre() : double
+ deplacerXY(double dx, double dy): void + getTypeForme(): String
+ distance(Point p) : double

Rectangle Ellipse
- longueur : double - grandRayon : double
- largeur : double - petitRayon : double

+ <<Rectangle>>(Point p, double + <<Ellipse>>(Point p, double


longueur, double largeur) grandRayon, double petitRayon)
+ surface(): double + surface(): double
+ perimetre(): double + perimetre(): double
+ getTypeForme(): String + perimetre(String): double
+ getTypeForme(): String

Cercle
Carre - rayon : double
- cote : double + <<Cercle>>(Point p, double rayon)
+ <<Carre>>(Point p, double cote) + getDiametre() : int
+ getTypeForme(): String + getTypeForme(): String

4/11
AU. : 2019/2020/Session d’Automne
Filière : LST Génie Logiciel, S5
Module : I511
Professeur : M.OUALLA

La classe Point :
package exercice7;

public class Point {


//attributs
private double abscisse;
private double ordonnee;

//Constructeurs
public Point() {
this.abscisse = 0;
this.ordonnee = 0;

}
public Point(double abscisse, double ordonnee) {
this.abscisse = abscisse;
this.ordonnee = ordonnee;
}

//getters et setters
public double getAbscisse() {
return abscisse;
}
public void setAbscisse(double abscisse) {
this.abscisse = abscisse;
}
public double getOrdonnee() {
return ordonnee;
}
public void setOrdonnee(double ordonnee) {
this.ordonnee = ordonnee;
}

public void setPoint(double abscisse, double ordonnee) {


this.abscisse = abscisse;
this.ordonnee = ordonnee;
}
//Les autres méthodes
public void deplacerX(double dx) {
this.abscisse += dx;
}
public void deplacerY(double dy) {
this.ordonnee += dy;
}
public void deplacerXY(double dx, double dy) {
this.abscisse += dx;
this.ordonnee += dy;
}
public double distance(Point p) {
return Math.sqrt(Math.pow(this.abscisse - p.abscisse, 2)
+ Math.pow(this.ordonnee - p.ordonnee, 2) );
}

public String toString() {


return "(" + this.abscisse + ", " + this.ordonnee +")";
}
}

5/11
AU. : 2019/2020/Session d’Automne
Filière : LST Génie Logiciel, S5
Module : I511
Professeur : M.OUALLA

La classe Forme :
package exercice7;

public class Forme {


protected Point p;

public Forme(Point p) {
this.p = p;
}
// Les getters et les setters
public Point getP() {
return p;
}
public void setP(Point p) {
this.p = p;
}
//Les méthodes
public void deplacerForme(double dx, double dy) {
this.p.deplacerXY(dx, dy);
}

public String getTypeForme() {


return "La forme ";
}
public double perimetre() {
return 0.0;
}
public double surface() {
return 0.0;
}
public String toString() {
return this.getTypeForme() + "(" + this.p;

}
//Une méthode pour ajuster la précision des nombres réels
public double ajuster(double nbre) {
return Math.round(nbre*100)/100.0;
}
}

La classe Rectangle :
package exercice7;

public class Rectangle extends Forme {


protected double longueur;
protected double largeur;

public Rectangle(Point p, double longueur, double largeur) {


super(p);
this.longueur = longueur;
this.largeur = largeur;
}
public double getLongueur() {
return longueur;
}
public void setLongueur(double longueur) {
this.longueur = longueur;
}

6/11
AU. : 2019/2020/Session d’Automne
Filière : LST Génie Logiciel, S5
Module : I511
Professeur : M.OUALLA

public double getLargeur() {


return largeur;
}
public void setLargeur(double largeur) {
this.largeur = largeur;
}
@Override
public double perimetre() {
return ajuster((this.largeur + this.longueur) * 2);
}
@Override
public double surface() {
return ajuster(this.largeur * this.longueur);
}

@Override
public String getTypeForme() {
return super.getTypeForme() + "Rectangle";
}

public String toString() {


return super.toString() + ","
+ longueur
+ " x "
+ largeur
+ ")";
}

La classe Ellipse :
package exercice7;

public class Ellipse extends Forme {


private double grandRayon;
private double petitRayon;

public Ellipse(Point p,double grandRayon, double petitRayon) {


super(p);
this.grandRayon = grandRayon;
this.petitRayon = petitRayon;
}

public double getGrandRayon() {


return grandRayon;
}

public void setGrandRayon(double grandRayon) {


this.grandRayon = grandRayon;
}

public double getPetitRayon() {


return petitRayon;
}

public void setPetitRayon(double petitRayon) {


this.petitRayon = petitRayon;
}

7/11
AU. : 2019/2020/Session d’Automne
Filière : LST Génie Logiciel, S5
Module : I511
Professeur : M.OUALLA

@Override
public String getTypeForme() {
return super.getTypeForme() + "Ellipse";
}

// p=2*PI * racine((a2+b2)/2)
@Override
public double perimetre() {
return ajuster(2 * Math.PI
* Math.sqrt((Math.pow(grandRayon, 2)
+ Math.pow(petitRayon, 2))/2));
}

// p= PI*(3(a+b)-racine((3a+b)(a+3b) ))
// et methode = "Ramanujan"
public double perimetre(String methode) {
return ajuster(Math.PI * (
3 * (grandRayon + petitRayon)
- Math.sqrt((3 * grandRayon + petitRayon)
* (grandRayon + 3 * petitRayon))
));
}

@Override
public double surface() {
return ajuster(Math.PI * grandRayon * petitRayon);
}

public String toString() {


return super.toString() + ","
+ this.grandRayon
+ " x "
+ this.petitRayon
+ ")";
}
}

La classe Carre :
package exercice7;

public class Carre extends Rectangle {


private double cote;

public Carre(Point p, double cote) {


super( p, cote, cote);
this.cote = cote;
}
public double getCote() {
return cote;
}
public void setCote(double cote) {
this.cote = cote;
}

@Override
public String getTypeForme() {
return "La forme Carré" ;
}

8/11
AU. : 2019/2020/Session d’Automne
Filière : LST Génie Logiciel, S5
Module : I511
Professeur : M.OUALLA

public String toString() {


return this.getTypeForme()
+ "(" + this.p
+ ", " + this.cote
+ ")";
}

La classe Cercle :
package exercice7;

public class Cercle extends Ellipse {


private double rayon;

public Cercle(Point p, double rayon) {


super(p, rayon,rayon);
this.rayon = rayon;
}

public double getRayon() {


return rayon;
}

public void setRayon(double rayon) {


this.rayon = rayon;
}
public double getDiametre() {
return rayon*2;
}

@Override
public String getTypeForme() {
return "La forme Cercle";
}

public String toString() {


return this.getTypeForme()
+ "(" + this.p
+ ", "
+ this.rayon
+ ")";
}
}

La classe TestFormes :
package exercice7;

public class TestFormes {

public static void main(String[] args) {


Point p = new Point(3,4);

Forme f = new Forme(p);


Rectangle r = new Rectangle(new Point(2,5), 10, 6);
Carre c = new Carre(new Point(1,4), 10);

9/11
AU. : 2019/2020/Session d’Automne
Filière : LST Génie Logiciel, S5
Module : I511
Professeur : M.OUALLA

Ellipse el = new Ellipse(p, 7,2);


Cercle cr = new Cercle(new Point(), 7);

//Afficher les formes


System.out.println("Afficher les formes :");
System.out.println(f);
System.out.println(r);
System.out.println(c);
System.out.println(el);
System.out.println(cr);

//Déplacer les formes


System.out.println();
System.out.println("Déplacer les formes :");
f.deplacerForme(1, 2);
System.out.println(f);
r.deplacerForme(1, 2);
System.out.println(r);
c.deplacerForme(1, 2);
System.out.println(c);
el.deplacerForme(1, 2);
System.out.println(el);
cr.deplacerForme(1, 2);
System.out.println(cr);

//Périmètre
System.out.println();
System.out.println("Périmètre :");
System.out.println("Périmètre de " + r + " est: " +
r.perimetre());
System.out.println("Périmètre de " + c + " est: " +
c.perimetre());
System.out.println("Périmètre de " + el + " est: " +
el.perimetre());
System.out.println("Périmètre 2 de " + el + " est: " +
el.perimetre("Ramanujan"));
System.out.println("Périmètre de " + cr + " est: " +
cr.perimetre());
System.out.println("Périmètre 2 de " + cr + " est: " +
cr.perimetre("Ramanujan"));

//Surface
System.out.println();
System.out.println("Surface :");
System.out.println("Surface de " + r + " est: " + r.surface());
System.out.println("Surface de " + c + " est: " + c.surface());
System.out.println("Surface de " + el + " est: " + el.surface());
System.out.println("Surface de " + cr + " est: " + cr.surface());
}
}

Le résultat de ce programme est :


Afficher les formes:
La forme ((3.0, 4.0)
La forme Rectangle((2.0, 5.0),10.0 x 6.0)
La forme Carré((1.0, 4.0), 10.0)
La forme Ellipse((3.0, 4.0),7.0 x 2.0)
La forme Cercle((0.0, 0.0), 7.0)

10/11
AU. : 2019/2020/Session d’Automne
Filière : LST Génie Logiciel, S5
Module : I511
Professeur : M.OUALLA

Déplacer les formes:


La forme ((4.0, 6.0)
La forme Rectangle((3.0, 7.0),10.0 x 6.0)
La forme Carré((2.0, 6.0), 10.0)
La forme Ellipse((5.0, 8.0),7.0 x 2.0)
La forme Cercle((1.0, 2.0), 7.0)

Périmètre :
Périmètre de La forme Rectangle((3.0, 7.0),10.0 x 6.0) est: 32.0
Périmètre de La forme Carré((2.0, 6.0), 10.0) est: 40.0
Périmètre de La forme Ellipse((5.0, 8.0),7.0 x 2.0) est: 32.34
Périmètre 2 de La forme Ellipse((5.0, 8.0),7.0 x 2.0) est: 30.5
Périmètre de La forme Cercle((1.0, 2.0), 7.0) est: 43.98
Périmètre 2 de La forme Cercle((1.0, 2.0), 7.0) est: 43.98

Surface :
Surface de La forme Rectangle((3.0, 7.0),10.0 x 6.0) est: 60.0
Surface de La forme Carré((2.0, 6.0), 10.0) est: 100.0
Surface de La forme Ellipse((5.0, 8.0),7.0 x 2.0) est: 43.98
Surface de La forme Cercle((1.0, 2.0), 7.0) est: 153.94

11/11

Vous aimerez peut-être aussi