[tab name=’Exercice Java’]
Cet exercice, permet de travailler les classes et les méthodes abstraites, les conversions de type explicites et votre compréhension générale des hiérarchies de classes.
Votre grand-mère a besoin d’un programme Java pour gérer sa collection d’ustensiles de cuisine anciens, plus précisément des assiettes (rondes ou carrées) et des cuillères. Vous trouverez ci-dessous une version incomplète de son programme Collection. Les 5 objets créés sont stockés dans le tableau us qui est de type Ustensile[].
Il vous est demandé de compléter le programme selon les indications dans les quatre questions ci-après. Pensez à profiter au maximum des possibilités offertes par Java pour éviter la duplication inutile d’instructions dans les classes et les méthodes.
class Collection { public static void main(String[] args) { Ustensile[] us = new Ustensile[5]; us[0] = new AssietteRonde(1926, 8.4); us[1] = new Cuillere(1881, 7.3); us[2] = new AssietteCarree(1935, 5.6); us[3] = new Cuillere(1917, 8.8); us[4] = new AssietteRonde(1837, 5.4); afficherCuilleres(us); afficherSurfaceAssiettes(us); afficherValeurTotale(us); } static void afficherCuilleres(Ustensile[] us) { int nbCuilleres = 0; for (int i = 0; i < us.length; i++) { // A compléter } System.out.println("Il y a " + nbCuilleres + " cuillères."); } static void afficherSurfaceAssiettes(Ustensile[] us) { double somme = 0; for (int i = 0; i < us.length; i++) { // A compléter } System.out.println("Surface totale des assiettes : " + somme); } static void afficherValeurTotale(Ustensile[] us) { double somme = 0; for (int i = 0; i < us.length; i++) { // A compléter } System.out.println("Valeur totale de la collection : " + somme); } }
Hiérarchie de classes
Il convient de modéliser les objets de la collection avec une hiérarchie de 5 classes comme indiqué dans la liste ci-dessous. Ecrivez le code de cette hiérarchie de classes, y compris les variables d’instance et les constructeurs. Vous pouvez ajouter les nouvelles classes au fichier Collection.java, si vous voulez, ou bien utiliser des fichiers séparés.
Evitez de dupliquer inutilement des instructions. La méthode main du programme Collection ci-dessus vous montre la façon d’appeler les constructeurs des classes qui sont instanciables.
- Chaque Ustensile a une annee de fabrication qui est une valeur int. Un Ustensile est soit une Assiette, soit une Cuillere. Il n’est pas possible d’instancier la classe Ustensile.
- Une Assiette est soit une AssietteRonde, soit une AssietteCarree. Il n’est pas possible d’instancier la classe Assiette.
- Chaque AssietteRonde à un rayon qui est une valeur double.
- Chaque AssietteCarree à un cote qui est une valeur double.
- Chaque Cuillere à une longueur qui est une valeur double.
Comptage
Complétez le code de la méthode afficherCuilleres pour qu’elle calcule et affiche le nombre d’objets de type Cuillere qui sont stockés dans le tableau us. Par exemple, le code de la méthode main ci-dessus donne lieu à l’affichage suivant:
Il y a 2 cuillères.
Surface totale
Complétez le code de la méthode afficherSurfaceAssiettes pour qu’elle calcule et affiche la somme des surfaces de toutes les assiettes stockées dans le tableau us, c’est-à-dire les assiettes rondes et les assiettes carrées. Il sera nécessaire de compléter la hiérarchie des classes avec des méthodes de calcul de surface. Evitez de dupliquer inutilement des instructions.
La surface d’une assiette se calcule comme suit:
- AssietteRonde : 3.14 * rayon * rayon
- AssietteCarree : cote * cote
Par exemple, le code de la méthode main ci-dessus donne lieu à l’affichage suivant:
Surface totale des assiettes : 344.48080000000004
Valeur totale des ustensiles
Complétez le code de la méthode afficherValeurTotale pour qu’elle calcule et affiche la somme des valeurs de tous les ustensiles stockés dans le tableau us. Il sera nécessaire de compléter la hiérarchie des classes avec des méthodes de calcul de valeur. Evitez de dupliquer inutilement des instructions.
La valeur d’un ustensile se calcule comme suit:
- Cuillere et AssietteRonde : Si l’ustensile a moins de 50 ans, il vaut 0 francs. Sinon, il vaut 1 franc pour chaque année qu’il a de plus de 50 ans, c’est-à-dire (2009 - annee - 50). Par exemple, une AssietteRonde ou une Cuillere fabriquée en 1943 vaut 16 francs.
- AssietteCarree : 5 fois la valeur qu’elle aurait eue en étant ronde (car les assiettes carrées sont plus rares). Par exemple, une AssietteCarree fabriquée en 1943 vaut 5 * 16 francs.
Par exemple, le code de la méthode main ci-dessus donne lieu à l’affichage suivant:
Valeur totale de la collection : 395.0
[/tab][tab name=’Correction’]
class Collection { // Cette variable stocke l'année actuelle. Vous verrez plus tard comment // utiliser la classe Data fournie par Java pour obtenir cette information // dynamiquement. private final static int CURRENT_YEAR = 2009; public static void main(String[] args) { Ustensile[] us = new Ustensile[5]; us[0] = new AssietteRonde(1926, 8.4); us[1] = new Cuillere(1881, 7.3); us[2] = new AssietteCarree(1935, 5.6); us[3] = new Cuillere(1917, 8.8); us[4] = new AssietteRonde(1837, 5.4); afficherCuilleres(us); afficherSurfaceAssiettes(us); afficherValeurTotale(us); } static void afficherCuilleres(Ustensile[] us) { int nbCuilleres = 0; for (int i = 0; i < us.length; i++) { if (us[i] instanceof Cuillere) { nbCuilleres++; } } System.out.println("Il y a " + nbCuilleres + " cuillères."); } static void afficherSurfaceAssiettes(Ustensile[] us) { double somme = 0; for (int i = 0; i < us.length; i++) { if (us[i] instanceof Assiette) { somme = somme + ((Assiette) us[i]).calculerSurface(); } } System.out.println("Surface totale des assiettes : " + somme); } static void afficherValeurTotale(Ustensile[] us) { double somme = 0; for (int i = 0; i < us.length; i++) { somme = somme + us[i].calculerValeur(CURRENT_YEAR); } System.out.println("Valeur totale de la collection : " + somme); } } abstract class Ustensile { private int annee; public Ustensile(int annee) { this.annee = annee; } public double calculerValeur(int anneeActuelle) { int age = (anneeActuelle - getAnnee()); double valeur = 0; if (age > 50) { valeur = age - 50; } return valeur; } public int getAnnee() { return annee; } } abstract class Assiette extends Ustensile { public Assiette(int annee) { super(annee); } public abstract double calculerSurface(); } class AssietteRonde extends Assiette { private double rayon; public AssietteRonde(int annee, double rayon) { super(annee); this.rayon = rayon; } public double calculerSurface() { return (3.14 * getRayon() * getRayon()); } public double getRayon() { return rayon; } } class AssietteCarree extends Assiette { private double cote; public AssietteCarree(int annee, double cote) { super(annee); this.cote = cote; } public double calculerSurface() { return (getCote() * getCote()); } public double calculerValeur(int anneeActuelle) { double valeur = 5 * super.calculerValeur(anneeActuelle); return valeur; } public double getCote() { return cote; } } class Cuillere extends Ustensile { private double longueur; public Cuillere(int annee, double longueur) { super(annee); this.longueur = longueur; } public double getLongueur() { return longueur; } }
[/tab][end_tabset skin= »ginger » ]