Vous êtes sur la page 1sur 6

AU.

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

TP N°5 - Solutions : Héritage, polymorphisme,


classes abstraites et interfaces
Exercice 1:
Polynome1D p1 = new Polynome1D(4,3);
p1.affiche();
Le type réel (type dynamique) de la variable p1 est Polynome1D, donc l’instruction
p1.affiche() fait appel à affiche() de la classe Polynome1D. Dans cette méthode
l’instruction if(!(this instanceof Polynome2D)) permet de vérifier le type de p1. En effet
dans ce cas-là p1 est une instance de Polynome1D. Donc, le résultat sera : 1er degré:
P(x)=3x + 4
System.out.println(" image("+ x +") = " + p1.image(x));
On fait appel à la méthode image() définie dans Polynome1D. Le résultat d’affichage est :
image(2) = 10
Polynome1D p2 = new Polynome2D(4,3,2);
p2.affiche();
Le type réel de la variable p2 est Polynome2D, donc l’instruction p2.affiche() fait appel à
affiche() de la classe Polynome1D puisque la classe Polynome2D n’a pas redéfinie cette
méthode. Dans cette méthode l’instruction if(!(this instanceof Polynome2D)) permet de
vérifier le type de p2. En effet dans ce cas-là p2 est une instance de Polynome2D. Donc,
le résultat sera : 2ème degré: P(x)=2x2 + 3x + 4
System.out.println(" image("+ x +") = " + p2.image(x));
On fait appel à la méthode image() redéfinie dans Polynome2D (Polymorphisme). Le
résultat d’affichage est : image(2) = 18
p2 = new Polynome3D(4,3,2,2);
p2.affiche();
Le type réel de la variable p2, après l’opération d’affectation, est Polynome3D, donc
l’instruction p2.affiche() fait appel à affiche() de la classe Polynome3D (Polymorphisme).
Dans cette méthode, on appelle affiche() de la superclasse qui est Polynome2D et qui n’a
pas redéfinit cette méthode, par conséquence, on remonte vers la classe supérieure qui est
Polynome1D. Ensuite, on exécute le reste des instructions. Donc, le résultat final sera :
2ème degré: P(x)=2x2 + 3x + 4
3ème degré: P(x)=2x3 + 2x2 + 3x + 4
System.out.println(" image("+ x +") = " + p2.image(x));
On fait appel à la méthode image() redéfinie dans Polynome3D (Polymorphisme). Le
résultat d’affichage est : image(2) = 34

En fin, ce programme fournit le résultat suivant :


1er degré: P(x)=3x + 4
image(2) = 10
2ème degré: P(x)=2x2 + 3x + 4
image(2) = 18
2ème degré: P(x)=2x2 + 3x + 4
3ème degré: P(x)=2x3 + 2x2 + 3x + 4
image(2) = 34

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

Exercice 2:

D’après ce programme, notre application possède la classe Menuisier et la classe Plombier


qui héritent de la classe Personne. On peut déduire aussi que chaque objet Personne possède
un attribut d’instance nom et une méthode affiche().
L’instruction personnes[i].affiche() permet de choisir la méthode appropriée à l’objet
appelant selon son type réel (Polymorphisme).
Le code de ces différentes classes est le suivant :

package exrecice2;

class Personne{
protected String nom;

public Personne(String nom) {


this.nom = nom;
}

public void afficher() {


System.out.print("Je suis " + nom );
//System.out.println("Je suis " + nom + " le " +
this.getClass().getSimpleName());
}
}

class Menuisier extends Personne{


public Menuisier(String nom) {
super(nom);
}
public void afficher() {
super.afficher();
System.out.println(" le Menuisier");
}
}

class Plombier extends Personne{


public Plombier(String nom) {
super(nom);
}
public void afficher() {
super.afficher();
System.out.println(" le Plombier");
}
}

public class TestMetiers {


public static void main(String[] argv) {
Personne[] personnes = new Personne[3] ;
personnes[0] = new Menuisier( "Mohamed" ) ;
personnes[1] = new Plombier( "Ali" ) ;
personnes[2] = new Menuisier( "Rachid" ) ;
for( int i=0 ; i< personnes.length ; i++ )
personnes[i].afficher() ;
}
}

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

Exercice 3:
Modification la classe de test de l’exercice 7 (TPN°4), en ajoutant une variable de type liste
(ArrayList) permettant de regrouper les différents objets Forme crées.
La classe modifiée :
package exrecice3;
import java.util.ArrayList;
import java.util.Arrays;

public class TestFormePoly {

public static void main(String[] args) {


Point p = new Point(3,4);

Rectangle r = new Rectangle(new Point(2,5), 10, 6);


Carre c = new Carre(new Point(1,4), 10);
Ellipse el = new Ellipse(p, 7,2);
Cercle cr = new Cercle(new Point(), 7);

ArrayList<Forme> formes =
new ArrayList<>(Arrays.asList(r,c,el,cr));

for(Forme f : formes) {
System.out.println(f);

f.deplacerForme(1, 2);
System.out.println("Déplacement par (1,2) de " + f);

System.out.println("Périmètre de " + f + " est: "


+ f.perimetre());
if(f instanceof Ellipse)
System.out.println("Périmètre 2 de " + f
+ " est: " + ((Ellipse)f).perimetre("Ramanujan"));

System.out.println("Surface de " + f + " est: "


+ f.surface());
System.out.println("---------------------------------");
System.out.println();
}
}
}

Exercice 4:

1) Soit une interface Java I, et deux classes concrètes C1 et C2 qui l'implémentent.


Lesquelles des déclarations suivantes sont correctes ou non ? Pourquoi ?
1. I x = new I () : FAUX, on n’instancie pas une interface.
2. C1 y = new C1 () : CORRECT, déclaration suivie d’instanciation par une classe
concrète.
3. I[] z = {new C1 (), new C2 ()} : CORRECT, les deux classes C1 et C2 sont
différentes mais elles implémentent la même interface, càd que les objets de ces
deux classes ont aussi le même type qui est I.

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

4. C1 w = new C2 () : FAUX, on déclare un objet de type C1 et on instancie avec


une autre C2 tel que C1 et C2 n’ont pas aucune relation (types incompatibles).

2) Peut-on écrire le code suivant : A a = new B() ;


1. Si A est une classe abstraite, dérivée par la classe B ?
Oui, à condition que la classe B soit une classe concrète (pas abstraite)
2. Si A est une interface, implémentée par une classe B ?
Oui, à condition que la classe B soit une classe concrète (pas abstraite)
3) Soit une classe C qui implémente les deux interfaces I1 et I2.

Que se passe-t-il si les deux interfaces I1 et I2 déclarent une même méthode f()? Une
même constante x ?
Solution :
Considérons le programme suivant :
interface I1{
public void f();
final int x =10;
}
interface I2{
public void f();
final int x =100;
}
class C implements I1,I2{
public void f() {
System.out.println(x);
}
}
La classe C implémente les deux interfaces I1 et I2, donc elle doit définir toutes les
méthodes fournies par ces deux interfaces, ce qui est le cas pour la méthode f(). Même si
les deux interfaces déclarent une même méthode, la classe C va la redéfinir et chaque
objet de cette classe utilisera donc une seule copie de cette méthode qui est celle définie
dans cette classe. En effet, il n’y aura pas d’ambiguïté.
En revanche, la définition d’une même constante par deux interfaces provoquera une
ambiguïté d’utilisation dans une classe qui implémente ces deux interfaces. Dans
l’instruction System.out.println(x), on ne pourra pas savoir quel x on va utiliser, est ce que
c’est celui de I1 ou bien celui de I2. Cette situation provoque une ambiguïté.

Exercice 5:

L’interface IOperation :
package exrecice5;
public interface IOperation {
public Object plus(Object o);
public Object moins(Object o);
}

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

La classe Nombre :
package exrecice5;

public abstract class Nombre {


String nom;

public Nombre(String nom){


this.nom = nom;
}

abstract void afficheAvecNom();


abstract void afficheSansNom();
}

La classe Reel :
package exrecice5;

public class Reel extends Nombre implements IOperation{


double x;

public Reel(String nom, double x) {


super(nom);
this.x = x;
}

//Les méthodes de l'interface IOperation


public Object plus(Object r) {
return new Reel("", this.x + ((Reel)r).x);

}
public Object moins(Object r) {
return new Reel("", this.x - ((Reel)r).x);
}

//La méthode de la classe Affichage


void afficheAvecNom() {
System.out.println(nom + " = " + x);
}
void afficheSansNom() {
System.out.println(x);
}
}

La classe Complexe :
package exrecice5;

public class Complexe extends Nombre implements IOperation {


int im;
int re;

public Complexe(String nom, int im, int re) {


super(nom);
this.im = im;
this.re = re;
}

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

//Les méthodes de l'interface IOperation


public Object plus(Object c) {
return new Complexe("", this.im + ((Complexe)c).im ,
this.re + ((Complexe)c).re);

}
public Object moins(Object c) {
return new Complexe("", this.im - ((Complexe)c).im ,
this.re - ((Complexe)c).re);
}

//La méthode de la classe Affichage


void afficheAvecNom() {
System.out.println(nom + " = " + re + " + " + im + "i");
}
void afficheSansNom() {
System.out.println(re + " + " + im + "i");
}
}

La classe Test :
package exrecice5;

public class Test {

public static void main(String[] args) {


Reel r1 = new Reel("r1",14.5);
Reel r2 = new Reel("r2",10);

Complexe c1 = new Complexe("c1",6,2);


Complexe c2 = new Complexe("c2",-2,4);

/*Nombre[] nombres = {r1,r2,c1,c2};

for(Nombre a : nombres) {
a.afficheAvecNom();
}*/

IOperation[] nombres = {r1,r2,c1,c2};

for(IOperation a : nombres) {
((Nombre)a).afficheAvecNom();
}

System.out.println("===================");

Reel r = (Reel)(r1.plus(r2));
System.out.print("r1 + r2 = ");
r.afficheSansNom();

Complexe c = (Complexe)(c1.plus(c2));
System.out.print("c1 + c2 = ");
c.afficheSansNom();
}
}

6/6

Vous aimerez peut-être aussi