Programmation Orientée Objet
Mohamed Lassoued
TD Chapitre 3 : Héritage Exercice 1 Public class A{ private String nom; …. ….. } class B extends A{ public String autre; …. ….. }
1. Est-ce qu’un objet de la classe B a un attribut nom ? 2. Est-ce qu’on peut accéder directement à nom dans la classe B ? pourquoi ? 3. Donner trois solutions pour pouvoir initialiser l’attribut nom dans le constructeur de B. Exercice 2.
Qu’affiche le programme suivant ? Expliquez. public class A { private int val=0; public static void affichePlus(int a) { a++; System.out.println(a); } public static void affichePlus(A a) { a.val++; System.out.println(a.val); } public static void main(String[] args) { A uneClasse = new A(); A uneAutreClasse = new A(); affichePlus (uneClasse.val); affichePlus (uneClasse.val); affichePlus (uneClasse); affichePlus (uneClasse); affichePlus (uneAutreClasse); affichePlus (uneAutreClasse); if (uneClasse == uneAutreClasse) System.out.println("Egales"); else System.out.println("Differentes"); } }
Exercice 3
Soit les classes suivantes : Fichier Figure.java public class Figure { double x, y ; public Figure() { x = 0 ; y = 0 ; } public Figure(double x, double y) { this.x = x ; this.y = y ; }
37
Programmation Orientée Objet
public String toString() { return "Position : (" + x + "," + y + ")" ;
Mohamed Lassoued
}
}
Fichier Cercle.java public class Cercle extends Figure { final static double PI = 3.141592564 ; private double rayon ; public Cercle() { rayon = 0 ; } public Cercle(double x, double y, double r) { super(x,y) ; rayon = r ; } public String toString() { return super.toString() + " Rayon : " + rayon ; } }
Fichier TestFigure.java : public class TestFigure { public static void main(String[] args) { Cercle c1,c2 ; c1 = new Cercle(1,1,3) ; c2 = new Cercle() ; System.out.println(c1.toString() + "\n" + c2.toString()) ; } }
1. Quelles sont les attributs de Figure hérités dans la classe Cercle ? 2. La variable rayon étant déclarée private, on ne peut pas la modifier de l’extérieur de la classe. Ajoutez une méthode setRayon pour pouvoir le fixer et getRayon pour le lire. 3. Ajoutez un attribut surface à la classe Cercle. Modifiez les méthodes setRayon et toString en conséquence. Ajoutez la méthode getSurface. Est-ce qu’on peut ajouter une méthode setSurface ? pourquoi ? 4. Ecrire une méthode estPlusGrand(Cercle c2) renvoyant true si le cercle c1 est plus grand que c2. Comment écrire une méthode ayant un comportement similaire, mais prenant les deux cercles en argument ? 5. Etendez la classe Cercle avec une classe Cylindre ajoutant une variable h pour la hauteur et une méthode volume. On ajoutera les constructeurs adéquats et on surchargera toString en conséquence. 6. Etendez la classe Cercle avec une classe CercleDeCouleur qui a en plus l’attribut entier coloration. La classe Cylindre hérite-t’elle de l’attribut de coloration ? Exercice 4 1. Créez une classe Personne correspondant qui contient les attributs et les méthodes ci -dessous.
Le genre de la personne sera décrit par un booléen dont la valeur vraie correspondra au genre masculin et la valeur fausse au genre féminin.
38
Programmation Orientée Objet
Mohamed Lassoued
| Personne |--------------------------|- nom: String |- prenom: String |- age: int |- genre: boolean |- adresse: String |--------------------------|+ Personne(String, String, boolean) |+ AfficheInfo(): String |+ nomPrenom(): String |+ genre(): boolean |+ age(int): int |+ adresse(String) : String |---------------------------
2. Ecrivez et testez la méthode AfficheInfo() (qui affiche à l’écran le nom et le prénom de la
personne, son âge, son genre et son adresse) . 3. Ecrivez les getteurs getnomPrenom():String et getgenre():boolean. Faites de même pour les
getteurs en lecture et écriture getage(int):int et getadresse(String):String. 4. Créez une classe TestPersonne qui contient le main et qui crée des personnes (3 Par exemple).
Faite appel dans cette méthode main aux méthodes AfficheInfo de ces objets. 5. Ajouter un constructeur sans paramètre. Surchargez le constructeur de la classe Personne. Pour
cela, déclarez et définissez un constructeur, à cinq paramètres (deux String, un boolean, un int, et un String), utilisant celui défini en a). 6. Créez une classe Société (à vous de déterminer quelques caractéristiques évidentes comme la
raison sociale) qui aura au moins comme attribut un objet directeur de type Personne. 7. Créez deux classes PersonnePhysique et PersonneMorale qui héritent de la classe Personne .
Modifiez en conséquence la classe Personne de telle manière à ce qu'elle représente bien génériquement le concept de personne (en particulier les attributs, les getteurs correspondants et la méthode toString()). La classe PersonneMorale se verra décrite notamment par un attribut déterminant sa forme juridique typeJuridique (un chaine de caractères ex: SARL, SA, ...). 8. Expliquez le mécanisme de construction d'une classe dérivée. Testez différents cas : appel
explicite ou non au constructeur de la classe mère ; existence ou non d’un constructeur sans arguments. 9. Dans chaque classe fille, redéfinissez la méthode AfficheInfo(), en faisant appel à la méthode de
la classe mère. 10. Changez les modificateurs d’accès des données membres de la classe mère, en remplaçant private par protected . Peut-on accéder à ces attributs depuis l’extérieur de la classe Personne ?
Quel danger cela présente-t-il (en termes d’encapsulation) ? Exercice 5
1. Créer la classe Personne qui contient
39
Programmation Orientée Objet
Mohamed Lassoued
a. un attribut nom de type String, b. un attribut age de type int. c. un constructeur avec deux paramètres (c.à.d. initialisant tous les attributs), d. une méthode afficher()qui affiche le nom et l’age. 2. Développer une classe nommée PersonneMain , publique, ne comportant pas de attribut et comportant une unique méthode main(). Au sein de cette méthode, créer une instance d’objet de type Personne et appeler sa méthode afficher(). 3. Ajouter un attribut à la classe Personne, de type tableau de réels
double[] MesNombres ;
avec 10 cases qui permet de représenter les divers chiffres de la personne. Adapter le constructeur, qui initialise les 10 éléments de ce tableau à 0, et la méthode afficher() qui affiche les éléments non nul du tableau. 4. Créer deux objets de type Personne, et appeler leurs méthodes afficher. 5. Au sein de la classe Personne, créer un constructeur par défaut, de signature Personne()appelant
le constructeur exhaustif de la question précédente au moyen du mot
clé this et initialisant respectivement les attributs nom et age à "SansNom" et 20. 6. Créer un constructeur de recopie, de signature Personne(Personne p) qui initialise les attributs de l’objet à ceux de p. Modifier la méthode main() de PersonneMain en créant 3 personnes, l’une à l’aide du constructeur exhaustif, une autre avec le constructeur par défaut et la dernière avec le constructeur de recopie. Ajouter dans main les instructions qui permet d’afficher les trois objets en appelant la méthode afficher() . 7. Créer une classe Enseignant héritant de Personne et ayant deux attributs : a. Un attribut
nbHeuresCours , de type primitif int,
b. Un attribut
Souriant,
de type primitif boolean.
c. Créer un constructeur exhaustif appelant le constructeur de la super classe (celui de Personne )
par
super
(cet appel doit être la première ligne du constructeur
d’Enseignant ), puis initialisant ses attributs propres (nbHeuresCours et Souriant ) 8. Développer une classe Etudiant héritant de Personne et ayant trois attributs : a. Un attribut Classe de type String, b. Un attribut noteMoyenne, de type primitif float, c. Un attribut faineant, de type primitif boolean. d. Créer un constructeur exhaustif appelant le constructeur de la classe parente (celui de Personne)
par super, puis initialisant ses attributs propres ( noteMoyenne
et
faineant).
9. Créer une classe
TesterEnseignantEleve
ne comportant pas de attribut et comportant
une unique méthode main(). Dans cette méthode, créer un objet de la classe Personne, de
40
Programmation Orientée Objet
Mohamed Lassoued
nom égal à "Salah" et d’âge égal à 35. Créer un Enseignant, de même nom et âge, ayant nbHeuresCours égal à 50 et Souriant mis à true. Toujour dans main, créer un Etudiant de nom "Ali", d’age égal à 20, ayant 12 comme noteMoyenne et fainéant mis à true. Appeler la méthode afficher() (qui est héritée de Personne) de ces trois instances. 10. Dans la classe
Personne ,
créer une nouvelle méthode
afficher(boolean compact)
afficher,
de signature
void
qui affiche selon l’un des formats suivants. Si compact est
égal à false, l’affichage est le même que celui de signature
void afficher() . Si compact
est égal à true, l’affichage sera de la forme [Nom, Age] 11. On se propose maintenant d’appliquer la Redéfinition de la méthode afficher(). Créer, au sein de la classe Enseignant (resp. dans la classe Etudiant) une méthode de signature void afficher()
qui appelle la méthode afficher() de Personne (au moyen de
super) puis qui affiche la chaîne "Enseignant"
(resp. "Etudiant").
12. Créer un tableau de 5 éléments de type Personne dans la méthode main()de la classe TesterEnseignantEleve
Enseignant
; initialiser ce tableau avec 2 instances d’objet de type
et 3 instances de type Etudiant. Effectuer une boucle for sur les éléments
du tableau ; dans le corps de la boucle, effectuer un appel à la méthode afficher s’il s’agit d’un
Etudiant
ou d’un
Enseignant
afficher() ,
puis
en se servant de l’opérateur
instanceof.
13. Modifier la méthode main() de
TesterEnseignantEleve
élaborée dans la question
précédente en ne conservant, dans le corps de la boucle for, qu’un appel à la méthode afficher()sur les cinq éléments du tableau.
Exercice 6
Les exemples suivants sont ils corrects ? Justifiez. class ClasseA { int a ; ClasseA() { System.out.println(a) ; } ClasseA(int a) { this.a = a ; this() ; }}
class ClasseB { int a ; } class ClasseB2 extends ClasseB { int b ; Ex2b2(int a,int b) { this.a = a ; this.b = b ; }
41
Programmation Orientée Objet
Mohamed Lassoued
} class ClasseC { int a ; Ex2c(int a) { this.a = a ; } } class ClasseC2 extends ClasseC { int b ; Ex2c2(int a,int b) { this.a = a ; this.b = b ; } } class ClasseD { public int a ; ClasseD () {} ClasseD (int a) { this.a = a ; } } class ClasseD2 extends ClasseD { private int a ; int b ; ClasseD2(int a,int b) { this.a = a ; this.b = b ; } } class ClasseE { public int a ; ClasseE(int a) { this.a = a ; } void seta(int c) { a=c ; } } class ClasseE2 extends ClasseE { private int a ; private ClasseE2(int a) { System.out.println("Bonjour") ; super(a) ; } private void seta(int c) { a=2*c ; } }
Exercice 7
1. Ecrivez une classe Vehicule contenant un champ :
private int nbPassager;
dans laquelle vous
définirez un constructeur Vehicule(int n) initialisant le nombre de passagers du véhicule, et une métode toString retournant une chaîne de caractères indiquant le nombre de passager d’un véhicule. 2. Écrivez maintenant une classe Velo étendant la classe Véhicule contenant un champ : 3.
private int nbRoues=2;
mais pas de constructeur. Le programme compile-t-il ? Justifiez votre réponse
et proposez une solution le cas échéant. 4. Ecrivez maintenant une classe Avion étendant la classe Véhicule contenant un champ : private int nbMoteur;
42
Programmation Orientée Objet
Mohamed Lassoued
5. En utilisant les méthodes this et super, écrivez un constructeur Avion(int nbP) puis Avion(int nbP, nbM) nbM
initialisant le nombre nbP de passagers de l’ Avion et le nombre
de moteurs.
6. Faites de même avec une classe Voiture et représentez la hiérarchie des classes sous forme d’un arbre. Proposez un nouveau schéma permettant de mieux « classer » les classes Avion, Velo et Voiture
et écrivez la/les classes suggérée(s).
Exercice 8
Toute réponse doit être justifiée. Vous proposerez une correction lorsque le code n’est pas correct. 1. Le code suivant est-il correct ? class A{ private String nom; } class B{ private A monA; B(String s){ monA = new A(); monA.nom = s; } }
2. La méthode suivante de la classe A doit-elle être statique ou dynamique ? boolean memeEnsemble(char a, char b){ if ( a == b%4 ) return true; return false; }
3. Le code suivant est-il correct ? class C extends B{ private int nb; C(String s, int a){ this.nb = a; super(s); } }
4. On ajoute à la classe B, la méthode public void affiche() . Le code suivant est-il correct ? int main(String []args){ B monB; switch(args[0]){ case "B": monB = new B("Bonjour"); break; case "C": monB = new C("Bonjour", 15); break; } monB.affiche(); }
5. On ajoute à la classe C, la méthode void mult(int coeff){ nb *= coeff; }
et dans le main l’instruction monB.mult(2); en dernière ligne. Le code obtenu est-il correct ?
43
Programmation Orientée Objet
Mohamed Lassoued
Exercice 9
Qu’affiche le programme suivant ? class A { int i = 1 ; int f() { return i ;} static char g() { return ’A’ ;} } class B extends A { int i = 2 ; int f () {return -i ;} static char g() { return ’B’ ;} } public class ClasseTesteur { public static void main(String args[]) { B b = new B() ; System.out.println(b.i) ; System.out.println(b.f()) ; System.out.println(b.g()) ; System.out.println(B.g()) ; A a = b ; System.out.println(a.i) ; System.out.println(a.f()) ; System.out.println(a.g()) ; System.out.println(A.g()) ; }}
Exercice 10
Dans l’exemple suivant, si l’on écrit dans B ((A)this).f() , quelle méthode est appelée ? Que se passe-t-il avec ((A)this).i? class A int i = int f() } class B int i = int f() }
{ 1 ; {return i ; } extends A { 2 ; {return super.f() * 2 + i ; }
Exercice 11
On considère les définitions de classes suivantes : class A { void f(A o) { System.out.println("void f(A o) dans A"); } } class B extends A { void f(A o) { System.out.println("void f(A o) dans B"); } }
1. Qu’affiche le fragment de programme suivant ? A a = new A(); A ab = new B(); B b = new B(); a.f(a); ab.f(a);
a.f(ab); ab.f(ab);
a.f(b); ab.f(b);
44
Programmation Orientée Objet
b.f(a);
Mohamed Lassoued
b.f(ab);
b.f(b);
2. On ajoute maintenant à la classe B la méthode suivante : void f(B o) { System.out.println("void f(B o) dans B"); }
Est-ce une redéfinition ou une surcharge ? Qu’affiche alors le fragment de programme ? 3. On ajoute finalement à la classe A la méthode suivante : void f(B o) { System.out.println("void f(B o) dans A");
}
Est-ce une redéfinition ou une surcharge ? Qu’affiche alors le fragment de programme? 4. Qu’affiche le fragment de programme suivant ? System.out.println(a instanceof A); System.out.println(ab instanceof A); System.out.println(b instanceof A); System.out.println(a instanceof B); System.out.println(ab instanceof B); System.out.println(b instanceof B);
45