Exercices java : Classes et héritage


4. Une étagère à confiture

    4.1. Reprendre l'exercice "Confitures" et créer une classe Etagere représentant une étagère pouvant contenir plusieurs pots de confitures avec les méthodes suivantes :

    • int getNbMaxConfitures() et int getNbConfitures() : les accesseurs qui renvoient respectivement le nombre maximal de pots de confiture, et le nombre de pots qu'elle contient effectivement;
    • void ajouter( Confiture ) : qui ajoute un pot de confiture sur l'étagère;
    • Confiture getConfiture( int ) : qui permet de récupérer le ième pot de confiture de l'étagère (la position du premier pot est 1);
    • int chercherConfiture( String, int ) : qui permet de chercher la position du premier pot de confiture de l'étagère repéré par son parfum et son année (renvoie 0 s'il n'y a pas de confiture de cette sorte);
    • Confiture enleverConfiture( int ) et Confiture enleverConfiture( String, int ) : pour la suppression d'un pot de confiture de l'étagère, soit par sa position, soit par son parfum et année; il faut alors "tasser" les confitures vers le début de l'étagère; les deux méthodes renvoient le pot de confiture que l'on a supprimé (null si aucun).
    • toString() : qui permet d'afficher le contenu d'une étagère. Le constructeur prendra en paramètre le nombre maximal de pots que peut contenir l'étagère. L'implémentation de l'étagère pourra se faire par un tableau ou un Vector, mais cela ne doit pas être visible de l'extérieur.
4.2. Créer un main qui permette de tester toutes ces méthodes ; tester avec 2 étagères

5.Une étagère générique...

Le but est de créer une nouvelle classe plus générique afin de pouvoir ranger sur notre étagère autre chose que des confitures. Pour cela, nous allons créer une hiérarchie de classes représentant tous les types de conserves que l'on souhaite stocker.

    5.1. Créer une classe abstraite Conserve représentant tous les types de conserves.

    Une conserve contiendra toujours :

    • un identifiant
    • le nom du cuisinier
    • la date (ou l'année de création et de stockage)
    • une méthode abstraite d'ajout sur une étagère abstract public void ajouter(Etagere e);
    • et toutes les méthodes d'accès et de modifications nécessaires...

    La méthode ajouter sera spécifique à chaque type de conserve, car certaines prendront plus de place que d'autres !

    5.2. Modifier maintenant la classe Confiture afin qu'elle hérite de la classe Conserve.

    5.3. Créer une nouvelle classe Moutarde spécialisant aussi la classe Conserve.

    Cette classe contiendra en plus des informations de la classe Conserve un entier type qui décrira le type de moutarde dont il s'agit. Cet attribut prendra une valeur parmi les constantes :

    • ANCIENNE = 0 : pour de la moutarde à l'ancienne;
    • CONDIMENT = 1 : pour de la moutarde condiment;
    • FORTE = 2 : pour de la moutarde forte.

    Ces constantes seront stockées comme attributs statiques de la classe Moutarde.

    Pour la méthode void ajouter(Etagere e) demandée par la superclasse Conserve, il faudra prendre en compte la spécificité des pots de moutarde à l'ancienne. Ceux-ci étant en terre cuite, ils sont très volumineux et nécessitent deux emplacements sur l'étagère. Pour les deux autres types de moutarde, ils s'ajoutent à l'étagère de manière normale.

    5.4. Tester ces classes avec un programme ajoutant plusieurs types de conserves sur une étagère.

    5.5. Pour finir, on peut généraliser nos étagères afin qu'elles stockent toutes sortes d'objets et pas uniquement des conserves. Pour cela, définir une interface Stockable décrivant le comportement d'un objet que l'on souhaite stocker sur notre étagère.

    Cette interface comportera uniquement une méthode void ajouter(Etagere e);

    Modifier toutes les classes précédentes afin qu'elles implémentent cette interface. Modifier aussi la classe Etagere qui maintenant gère un tableau de Stockable.

6. Trois petits points...

6.1 Créer une classe Point permettant de manipuler des points du plan. On la munira :

  • de deux attributs privés x et y réels correspondant à l'abscisse et à l'ordonnée de ce point;
  • d'un constructeur sans argument, qui crée le point de coordonnées (0,0);
  • d'un constructeur recevant deux arguments réels, qui sont respectivement l'abscisse et l'ordonnée du point;
  • de deux accesseurs public double getX() et public double getY() pour l'abscisse et l'ordonnée; on ne fournira pas de modificateurs;
  • d'une méthode public void translation ( double vx, double vy ) permettant de translater un point, ainsi que d'une méthode public Point imageParTranslation( double vx, double vy ) permettant de construire l'image d'un point par une translation de vecteur (vx,vy);
  • de la méthode public String toString() affichant les coordonnées du point sous la forme (x,y).

6.2 Tester cette classe avec le code suivant :

 public class Geometrie {
public static void main() {
Point p1, p2, p3;
p1 = new Point();
System.out.println( "Création du point p1 : " + p1 );
p2 = new Point( 1, 2 );
System.out.println( "Création du point p2 : " + p2 );

System.out.println( "\nTranslation de vecteur (3,4) ..." );

p1.translation( 3, 4 );
System.out.println( "Le point p1 après translation : " + p1 );

p3 = p2.imageParTranslation( 3, 4 );
System.out.println( "L'image du point p2 après translation : " + p3 );
System.out.println( "Mais p2 n'a pas changé, p2 : " + p2 );
}
}

Il faut obtenir le résultat suivant :

 Création du point p1 : (0, 0)
Création du point p2 : (1, 2)

Translation de vecteur (3,4) ...
Le point p1 après translation : (3, 4)
L'image du point p2 après translation : (4, 6)
Mais p2 n'a pas changé, p2 : (1, 2)

6.3 Ajouter à la classe précédente :

  • les méthodes public static double calculRayon( double x, double y ) et public static double calculAngle( double x, double y ), permettant d'obtenir, à partir des coordonnées cartésiennes (x, y) d'un point, ses coordonnées polaires.
    Rappel : les fonctions mathématiques usuelles sont définies dans la classe Math de java.lang.
  • les méthodes de classe permettant d'effectuer la conversion inverse : public static double calculAbscisse( double r, double t ) et public static double calculOrdonnee( double r, double t );
  • les méthodes public double getRayon() et public double getAngle() qui fournissent les coordonnées polaires d'un point.