Dans cette série, vous apprendrez à utiliser la notion de hiérarchie pour organiser vos classes. Comme pour la série précédente, il est important de comprendre chaque exercice et d'en étudier le corrigé pour une bonne prise en main des concepts de POO.
Le but de cet exercice est d'illustrer la notion d'héritage en utilisant une hiérarchie de figures géométriques. Pour simplifier, nous laisserons tous les accès de méthodes publics dans cet exercice.
Le fichier FiguresGeometriques.java, comporte les définitions des classes Rectangle et Cercle ci-dessous (similaire à ce que vous avez dans le code dans la série 6), ainsi qu'une ébauche de main:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
class FiguresGeometriques { public static void main(String[] args) { // A COMPLETER } } class Rectangle { private double largeur; private double longueur; public Rectangle(double largeur, double longueur) { this.largeur = largeur; this.longueur = longueur; } public double surface() { return largeur * longueur; } public double getLongueur() { return longueur; } public double getLargeur() { return largeur; } public void setLargeur(double l) { largeur = l; } public void setLongueur(double l) { longueur = l; } } class Cercle { // abscisse du centre private double x; // ordonnée du centre private double y; private double rayon; public Cercle(double x, double y, double r) { this.x = x; this.y = y; rayon = r; } public void affiche() { System.out.println("centre = (" + x + ", " + y + ")"); } public double getX() { return x; } public double getY() { return y; } public void setCentre(double x, double y) { this.x = x; this.y = y; } public double surface() { return Math.PI * rayon * rayon; } public boolean estInterieur(double x, double y) { return (((x - this.x) * (x - this.x) + (y - this.y) * (y - this.y)) <= rayon * rayon); } public double getRayon() { return rayon; } public void setRayon(double r) { if (r < 0.0) r = 0.0; rayon = r; } } |
Commençons par y ajouter la classe RectangleColore qui hérite de Rectangle.
Cette classe doit simplement avoir un attribut de plus, couleur, disons de type int.
[Essayez de le faire par vous même avant de regarder la solution qui suit]
Ceci se fait très simplement :
class RectangleColore extends Rectangle { } |
class RectangleColore extends Rectangle { private int couleur; } |
Pour rendre notre nouvelle classe plus réaliste (et utilisable) ajoutons lui un constructeur qui fera appel au constructeur de la classe parente :
public RectangleColore(double larg, double longueur, int c){ super(larg, longueur); couleur = c; } |
Testez avec ce main simple :
public static void main(String[] args) { RectangleColore r = new RectangleColore(4.3, 12.5, 4); System.out.println(r.getLargeur()); } |
Continuez en définissant la classe Figure. Celle-ci contient:
[Essayez de le faire par vous même avant de regarder la solution qui suit]
Pour la classe Figure, rien de particulier, et il suffit de déplacer les définitions correspondantes de la classe Cercle à la classe Figure (donc les supprimer de Cercle).
Puis on ajoute la méthode affiche et le constructeur :
class FiguresGeometriques { public static void main(String[] args) { RectangleColore r = new RectangleColore(1.2,3.4,12.3,43.2,4); r.affiche(); Cercle c = new Cercle (2.3, 4.5, 12.2); c.affiche(); } } class Figure { // abscisse du centre private double x; // ordonnee du centre private double y; public Figure(double x , double y){ this.x = x; this.y = y; } public void affiche() { System.out.println("centre = (" + x + ", " + y + ")"); } public double getX() { |
Venons-en à l'héritage proprement dit. Il faut spécifier les liens d'héritage aux deux classes concernées.
class Rectangle extends Figure { ... class Cercle extends Figure { ... |
puis modifier les constructeurs de manière appropriée :
//constructeur de la classe Cercle public Cercle(double x, double y, double r) { super(x,y); rayon=r; } ... //constructeur de la classe Rectangle public Rectangle(double x, double y,double larg, double longueur){ super(x,y); this.largeur = larg; this.longueur = longueur; } ... //constructeur de la classe RectangleColore public RectangleColore(double x, double y,double larg, double longueur, int c){ super(x,y,larg, longueur); couleur = c; } |
Pour la méthode d'affichage, supposons que l'on souhaite que, pour la classe Cercle, la méthode affiche également le rayon (mais continue d'afficher le centre).
Cela se fait en définissant dans la classe Cercle une méthode affiche utilisant la méthode masquée affiche de la super classe Figure :
class Cercle extends Figure { ... public void affiche(){ super.affiche(); System.out.println("rayon = " + rayon); } .. } |
On peut bien sûr faire de même avec les classes Rectangle et RectangleColore :
.. //dans la classe Rectangle public void affiche(){ super.affiche(); System.out.println("Largeur = " + largeur); System.out.println("Longeur = " + longueur); } .. //dans la classe RectangleColore public void affiche(){ super.affiche(); System.out.println("Couleur = " + couleur); } |
La méthode estInterieur de la classe Cercle doit être modifiée car l'accès direct aux attributs x et y, désormais hérités de Figure, n'est plus possible. Il faut passer par des getters.
Testez le programme avec la méthode main suivante :
public static void main(String [] args) { RectangleColore r = new RectangleColore(1.2,3.4,12.3,43.2,4); r.affiche(); Cercle c = new Cercle (2.3, 4.5, 12.2); c.affiche(); } |
Cette semaine vous devez visionner les vidéos de la semaine 3 du MOOC. Pour bien assimiler ce contenu, il est recommandé de faire les quiz des mêmes semaines: Quiz «Héritage».
Dans un fichier GestionVehicules.java, définissez une classe Vehicule qui a pour attributs des informations valables pour tout type de véhicule :
Définissez un constructeur prenant en paramètre les trois attributs correspondant à la marque, la date d'achat et le prix d'achat. Le prix courant sera calculé plus tard.
Définissez une méthode publique void affiche() qui affiche l'état de l'instance, c'est-à-dire la valeur de ses attributs.
Définissez deux classes Voiture et Avion, héritant de la classe Vehicule et ayant les attributs supplémentaires suivants :
Définissez, pour chacune de ces classes, un constructeur permettant l'initialisation explicite de l'ensemble des attributs, ainsi qu'une méthode affichant la valeur des attributs. Constructeurs et méthodes d'affichage devront utiliser les méthodes appropriées de la classe parente !
Ajoutez une méthode void calculePrix(int anneActuelle) dans la classe Vehicule qui, à ce niveau, fixe le prix courant au prix d'achat moins 1% par année (entre la date d'achat et la date actuelle).
Redéfinissez cette méthode dans les deux sous-classes Voiture et Avion de sorte à calculer le prix courant en fonction de certains critères, et mettre à jour l'attribut correspondant au prix courant :
Afin de tester les méthodes implémentées ci-dessus, complétez la méthode main comme suit :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
class GestionVehicules { // Pour repréesenter l'année courante: // Il est aussi bien sur possible d'utiliser la classe Date // pour r'ecupérer cette information automatiquement. private static int ANNEE_ACTUELLE = 2020; public static void main(String[] args) { Voiture[] garage = new Voiture[3]; Avion[] hangar = new Avion[2]; garage[0] = new Voiture("Peugeot", 2005, 147325.79, 2.5, 5, 180.0, 12000); garage[1] = new Voiture("Porsche", 1999, 250000.00, 6.5, 2, 280.0, 81320); garage[2] = new Voiture("Fiat", 2001, 7327.30, 1.6, 3, 65.0, 3000); hangar[0] = new Avion("Cessna", 1982, 1230673.90, "HELICES", 250); hangar[1] = new Avion("Nain Connu", 1993, 4321098.00, "REACTION", 1300); for (int i = 0; i < garage.length; i++) { garage[i].calculePrix(ANNEE_ACTUELLE); garage[i].affiche(); } for (int i = 0; i < hangar.length; i++) { hangar[i].calculePrix(ANNEE_ACTUELLE); hangar[i].affiche(); } } } |
Exemple d'exécution :
---- Voiture ---- marque : Peugeot, date d'achat : 2005, prix actuel : 95761.76350000002 2.5 litres, 5 portes, 180.0 CV, 12000.0 km. ---- Voiture ---- marque : Porsche, date d'achat : 1999, prix actuel : 94999.99999999997 6.5 litres, 2 portes, 280.0 CV, 81320.0 km. ---- Voiture ---- marque : Fiat, date d'achat : 2001, prix actuel : 3810.1960000000004 1.6 litres, 3 portes, 65.0 CV, 3000.0 km. ---- Avion à HELICES---- marque : Cessna, date d'achat : 1982, prix actuel : 923005.4249999999 250 heures de vol. ---- Avion à REACTION---- marque : Nain Connu, date d'achat : 1993, prix actuel : 3759355.26 1300 heures de vol.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
class Erreur { public static void main(String args[]) { E1 x = new E1(); E2 y = new E2(); E3 z = new E3(); E4 v = new E4(); E5 w = new E5(); System.out.println(x.a); // Correct ou faux ? System.out.println(y.c); // Correct ou faux ? System.out.println(z.b); // Correct ou faux ? System.out.println(v.c); // Correct ou faux ? System.out.println(w.a); // Correct ou faux ? } } class E1 { int a = 1; } class E2 extends E1 { int b = 2; } class E3 extends E2 { int c = 3; } class E4 extends E1 { int d = 4; } class E5 extends E4 { int e = 5; } |
Parmi les 5 EPFLiens, 3 sont des etudiants. Ils sont ici depuis en moyenne 6.2 ans Liste des EPFLiens: Etudiant regulier: Nom : Gaston Peutimide Annee : 2020 Section : SSC Moyenne : 6.0 Etudiant regulier: Nom : Yvan Rattrapeur Annee : 2016 Section : SSC Moyenne : 2.5 Etudiant d'echange: Nom : Bjorn Borgue Annee : 2018 Section : Informatique Uni d'origine : KTH Enseignant: Nom : Mathieu Matheu Annee : 2015 Laboratoire : LMEP Salaire : 10000 Section d'enseignement : Physique Secretaire: Nom : Sophie Scribona Annee : 2005 Laboratoire : LMT Salaire : 5000
Il s’agit dans cet exercice de proposer une conception modélisant une boîtes aux lettres en Java orienté-objet.
Une boîtes aux lettres recueille des lettres, des colis et des publicités.
Une lettre est caractérisée par :
Un colis est caractérisé par :
Une publicité est caractérisée par :
Voici les règles utilisées pour affranchir le courrier :
Les trois méthodes principales liées à la boîte aux lettre sont les suivantes :
1. une méthode affranchir() permettant d'associer à chaque courrier de la boîte, le montant nécessaire pour l'affranchir. Cette méthode retournera le montant total d'affranchissement du courrier de la boîte.
3. une méthode afficher() affichant le contenu de la boîte aux lettre (on indiquera alors quels courriers sont invalides).
2. une méthode courriersInvalides() calculant et retournant le nombre de courriers invalides présents
dans la boîte aux lettres.
Sur papier, commencez par dessiner une hiérarchie de classes permettant de mettre en oeuvre la conception suggérée en tenant compte des contraintes mentionnées. Vous spécifierez dans votre diagramme les classes, les attributs et les entêtes des méthodes (sans les corps). Les contraintes suivantes devront être respectées :
Implémentez ensuite le programme résultant de votre conception dans le fichier Poste.java
Avec le programme principal fourni, vous devriez avoir une exécution telle que (le prix indique le coùt d'affranchissement):
Le montant total d'affranchissement est de 47.4 Lettre Poids : 200.0 grammes Express : oui Destination : Chemin des Acacias 28, 1009 Pully Prix : 7.4 CHF Format : A3 Lettre (Courrier invalide) Poids : 800.0 grammes Express : non Destination : Prix : 0.0 CHF Format : A4 Publicité Poids : 1500.0 grammes Express : oui Destination : Les Moilles 13A, 1913 Saillon Prix : 15.0 CHF Publicité (Courrier invalide) Poids : 3000.0 grammes Express : non Destination : Prix : 0.0 CHF Colis Poids : 5000.0 grammes Express : oui Destination : Grand rue 18, 1950 Sion Prix : 25.0 CHF Volume : 30.0 litres Colis (Courrier invalide) Poids : 3000.0 grammes Express : oui Destination : Chemin des fleurs 48, 2800 Delemont Prix : 0.0 CHF Volume : 70.0 litres La boite contient 3 courriers invalides
Les devoirs du MOOC, même s'il ne sont pas notés pour vous, sont un bon moyen de vous entraîner aussi. Vous pouvez les soumettre à un correcteur automatique (autant de fois que vous le souhaitez) et recevoir un feedback. Cette semaine vous pouvez faire le devoir de la semaines 2 (encapsulation, constructeurs) et celui de la semaine 3 (héritage).
Dernière mise à jour: 08/11/2024 (Revision: 1.2)