CSC_3X061_EP - TD 3 : Objets

Auteurs : Alain Couvreur et Eric Fusy (original), Simon Bliudze (reprise 2023–2025)

1 Préambule

Avant de commencer ce TD, n’oubliez pas de faire le quiz. Attention temps limité !

Prétexte : Dans ce TD, on modélise de l’argent (dans différentes monnaies).

Motivation : Ce TD a pour but de vous familiariser avec les objets en Java.

1.1 Avant de commencer

Une fois déposé, votre programme va faire l’objet d’une validation automatique. Attention, si la validation dit “OK”, cela ne veut pas dire que votre programme est parfait, mais simplement qu’il a passé avec succès quelques tests qui détectent les erreurs les plus grossières.

2 Partie I : Les objets de base

2.1 Exercice 1 : Des objets pour les monnaies

Dans ce TD, on représentera tout d’abord les monnaies possibles par des objets de la classe Monnaie. Chaque objet de cette classe doit posséder deux champs :

Par le “taux de conversion par rapport à l’Euro” on entend l’équivalent d’un Euro dans la monnaie. Par exemple si la monnaie “Yuan” a un taux de 7.8 cela signifie que 1 Euro = 7.8 Yuans. (Le Yuan a demandé que son taux réel ne soit pas divulgué dans notre TD.)

Créez la classe Monnaie avec ces deux champs, et un constructeur qui prend deux arguments et crée un objet de type Monnaie avec les valeurs entrées en paramètre pour le nom et le taux.

Écrire les deux méthodes suivantes :

La classe Monnaie n’a pas besoin de fonction main, elle sera utilisée depuis des programmes écrits dans d’autres classes, comme le test ci-dessous.

Pour tester votre classe Monnaie, télécharger le programme Test01.java dans le répertoire src. Lors de son exécution, la sortie doit afficher exactement :

-- test Monnaie() et getTaux():
Yuan 7.8        <-- attendu
Yuan 7.8        <-- obtenu

-- test setTaux(double autreTaux) :
true 7.6        <-- attendu
true 7.6        <-- obtenu
-- test setTaux(double autreTaux) :
false 7.6       <-- attendu
false 7.6       <-- obtenu
-- test setTaux(double autreTaux) :
false 7.6       <-- attendu
false 7.6       <-- obtenu

La réussite de ce test ne prouve pas que votre classe est correcte. Il faut déposer pour soumettre à la validation automatique qui va faire passer des tests plus poussés.

Déposez ici le fichier Monnaie.java.

2.2 Exercice 2 : Des objets pour l’argent

On va représenter de l’argent par des objets de la classe Argent. Téléchargez le fichier Argent.java dans votre répertoire src :

import tc.TC;
public class Argent {
    // représentation interne de l'argent:
    // Champs d'objet
    private final int valeur;
    private final Monnaie monnaie;


    public Argent(int v) {
        this.valeur = v;
        this.monnaie = new Monnaie("Euro", 1.0);
    }

    public Argent(int v, Monnaie monnaie) {
        if (monnaie == null)
            throw new IllegalArgumentException("le parametre monnaie est null");
        this.valeur = v;
        this.monnaie = monnaie;
    }
    ...
}

Le champ monnaie correspond à la monnaie utilisée. Il est de type Monnaie.

Le champ valeur porte la valeur de cet objet exprimée en centimes à savoir : 1 Euro (respectivement Dollar/Livre/Yuan/Réal) = 100 centimes (respectivement cents/pence/fens/centavos) et sera donc représenté par la valeur 100.

Les champs valeur et monnaie sont

On vous fournit un constructeur public Argent(int v, Monnaie monnaie) qui crée un objet de la classe Argent de valeur v et de monnaie monnaie. On fournit un second constructeur public Argent(int v) qui par défaut crée des euros. Rappelons ici qu’il est possible pour une classe d’avoir deux constructeurs à condition que ces derniers aient des jeux de paramètres différents, ce qui est le cas ici.

Vous devez écrire des méthodes pour tester l’égalité entre objets. Il faut tout d’abord ajouter une méthode public boolean estEgalA(Monnaie m) à la classe Monnaie qui doit renvoyer true si et seulement si m n’est pas null et, de plus, les deux objets this et m sont égaux en tant que monnaies (ici cela veut dire qu’ils ont le même nom et le même taux).

On rappelle que l’on doit tester l’égalité de deux chaînes de caractères par la méthode equals de la classe String et surtout pas avec le test ==.

Ensuite, compléter la méthode public boolean estEgalA(Argent a) de la classe Argent, qui doit renvoyer true si et seulement si a n’est pas null et, de plus, les deux objets this et a ont la même valeur et la même monnaie. Il est demandé de faire appel à la méthode estEgalA de la classe Monnaie pour tester l’égalité des monnnaies.

Pour tester les deux méthodes estEgalA, le programme Test02.java doit afficher exactement :

-- test estEgalA() de Monnaie:
false, true, false      <-- attendu
false, true, false      <-- obtenu

-- test estEgalA() de Argent:
true, false, false, true        <-- attendu
true, false, false, true        <-- obtenu

Déposez ici les fichiers Monnaie.java et Argent.java.

3 Partie II : Lecture/Écriture et manipulation des objets

Les trop jeunes pour savoir de quoi s’agit-il peuvent, en dehors des heures de cours, aller voir la source.

3.1 Exercice 3 : Show Me the Money

On aura besoin de construire un objet de type String à partir d’un objet de type Argent (pour pouvoir l’afficher de manière lisible). Chaque classe Java possède une méthode public String toString() qui construit la représentation des objets de cette classe.

Vous devez écrire la méthode public String toString() dans la classe Argent. La chaîne de caractères renvoyée doit se composer de :

Par exemple : si x est un objet de type Argent tel que x.valeur est égal à 1234501 et x.monnaie est égal à "Dollar", alors x.toString() doit donner la chaîne

12345.01 Dollars

avec un espace avant Dollars et, bien entendu, sans aucun passage à la ligne.

On pourra s’aider des méthodes valeurEntiere() et valeurDecimale() de la classe Argent. Dans l’exemple, si la valeur est 12345.01, alors valeurEntiere() renvoie 12345 et valeurDecimale() renvoie 1.

On ajoutera également dans la classe Monnaie la méthode suivante que l’on devra utiliser pour la mise au pluriel du nom de la monnaie :

public String pluriel() { 
    return this.nom+"s"; 
}

Pour tester la méthode toString, le programme Test03.java doit afficher exactement :

-- test toString :
0.68 Euro       <-- attendu
0.68 Euro       <-- obtenu

-- test toString :
174.01 Dollars  <-- attendu
174.01 Dollars  <-- obtenu

Déposez ici le fichier Argent.java.

3.2 Exercice 4 : Conversion

On souhaite créer à partir d’un objet de la classe Argent un autre objet de la même classe mais d’une autre monnaie et dont la valeur se voit appliquer le taux de conversion courant entre les monnaies considérées

On rappelle que chaque objet monnaie de type Monnaie contient un champ taux donnant le montant représentant 1 Euro en unités de la monnaie.

Vous devez écrire la méthode public Argent convertir(Monnaie autreMonnaie) de la classe Argent. On supposera que l’argument autreMonnaie n’est pas null.

public Argent convertir(Monnaie autreMonnaie) renvoie un Argent _dont le champ monnaie est égal à autreMonnaie.

Si la monnaie référencée par autreMonnaie est égale à celle référencée par le champ monnaie alors on ne fait pas de conversion et on renvoie simplement l’objet appelant (qui est this).

ATTENTION : Une même monnaie peut être représentée par deux objets de la classe Monnaie différents.

Sinon, on construit et on renvoie un nouvel objet dont le champ valeur est obtenu à partir de la valeur de this à laquelle on applique le taux de conversion de la monnaie de this vers autreMonnaie. Noter qu’il faudra que valeur reste de type int. Rappelons donc que si l’on a un double d on peut le convertir en int en faisant (int)d.

Remarque : A cause des erreurs d’arrondi, les opérations usuelles sur les nombres flottants ne sont pas associatives. Ici, on prend la convention de calculer le taux de conversion entre les deux monnaies concernées, puis d’appliquer ce taux à la valeur initiale, plutôt que de calculer une valeur intermédiaire en euros qui serait ensuite de nouveau convertie. Bien sûr, on ne réalisera qu’une seule troncature en int, à la fin, pour éviter un cumul d’erreurs.

Pour tester la méthode convertir, exécuter le programme Test04.java qui doit afficher:

-- test convertir : redirection de sortie vers fichier Test04-sortie.txt

Maintenant, il faut vérifier que la sortie, qui a été renvoyée vers le fichier Test04-sortie.txt, est exactement identique au fichier de référence sortie04.txt (donné au début de cette feuille). On peut faire cela dans VSCode :

Déposez ici le fichier Argent.java.

3.3 Exercice 4-bis : Jouons avec le test

L’objectif suivant est de modifier le programme Test04 de manière à ce qu’il produise un nouveau fichier Test04-sortie-bis.txt dont le contenu serait exactement celui du fichier sortie04-bis.txt. Faire une copie de Test04.java sous le nom Test04b.java et changer le nom de la classe en conséquence.

Indication : Le fichier Test04b.java effectue et affiche différentes conversions (une sur chaque ligne). Lorsque les deux monnaies coïncident, une valeur booléenne est affichée en plus. Il faut compléter ce test de manière à ce qu’il effectue et affiche (sur chaque ligne) la conversion inverse, ainsi qu’un booléen indiquant si on est revenu au montant de départ. (Il faut, donc, supprimer l’affichage du booléen existant et le remplacer par le nouveau booléen demandé.) Ne modifiez que la méthode test et le nom du fichier de sortie dans main. La validation automatique demande que vous ne changiez pas les exemples qui sont testés.

Remarque : Pour chaque cas testé (chaque ligne affichée), les calculs doivent résulter, éventuellement de manière indirecte par les méthodes utilisées, dans exactement :

Note : Comment expliquez-vous que l’on ne retombe pas toujours sur le même montant lorsque l’on effectue une conversion puis la conversion inverse ?

Déposez ici le fichier Test04b.java.

3.4 Exercice 5 : Recherche de monnaie

En général les monnaies ont vocation à être stockées (avec leur taux courant) dans un tableau préexistant et on souhaite pouvoir rechercher une monnaie dans le tableau à partir de son nom.

Vous devez ajouter une méthode public static Monnaie trouverMonnaie(String s, Monnaie[] tab) dans la classe Monnaie. On supposera qu’aucune des entrées de tab n’est null et que s est également non null. En revanche, on fera attention au fait que l’argument s peut être le nom d’une monnaie au pluriel.

Pour tester la méthode trouverMonnaie(), exécuter le programme Test05.java qui doit afficher :

--Test recherche -- redirection de sortie vers fichier Test05-sortie.txt

Maintenant, il faut vérifier que la sortie, qui a été renvoyée vers le fichier Test05-sortie.txt, est exactement identique au fichier de référence sortie05.txt. Pour ce faire on procède à la comparaison comme expliqué dans la question précédente.

Déposez ici le fichier Monnaie.java.

3.5 Exercice 6 : Créer l’Argent à partir d’un String

On se donne un objet de type String de la forme "897123.65 Livres", et il s’agit de créer l’objet de type Argent correspondant (notamment, pour pouvoir ensuite construire des objets de type Argent à partir d’un fichier texte).

Pour découper un String en mots (séparés par des blancs), on utilisera la fonction TC.motsDeChaine(String) qui découpe un String en mots. Si par exemple l’entrée est "897123.65 Livres" cette fonction renverra un tableau de deux cases contenant respectivement les chaînes de caractères "897123.65" et "Livres". Deux blancs consécutifs sont considérés comme une seule séparation.

Pour traiter le terme "897123.65", on utilisera la fonction TC.decoupage(String,char) : cette méthode découpe l’argument String en morceaux, selon les occurrences du caractère donné en second argument, et elle renvoie un tableau de String contenant les morceaux, sans le caractère de découpage.

Par exemple,

String s = "abcdeabbc";
String[] mots = TC.decoupage(s,'e');

est équivalent à

String s = "abcdeabbc";
String[] mots = new String[]{"abcd", "abbc"};

De même,

String s = "abcdeabbc";
String[] mots = TC.decoupage(s,'b');

est équivalent à

String s = "abcdeabbc";
String[] mots = new String[]{"a", "cdea", "", "c"};

Ici, on considère qu’il y a un mot vide entre les deux b consécutifs.

Enfin, on utilisera la fonction Integer.parseInt(String) pour obtenir des entiers à partir des chaînes de caractères. Par exemple,

int x = Integer.parseInt("1234");

est équivalent à

int x = 1234;

Vous devez définir un troisième constructeur public Argent(String str, Monnaie[] tab) pour la classe Argent.

On supposera que l’argument str est bien formaté. L’objet de type Monnaie utilisé est celui obtenu (à l’aide de la méthode trouverMonnaie) en cherchant la monnaie de même nom dans le tableau tab passé en argument. On supposera que la monnaie recherchée existe toujours dans tab. On ne vous demande donc pas de faire de gestion d’erreur.

Pour tester la méthode Argent(String), le programme Test06.java doit afficher exactement :

-- test constructeur Argent(String) :
1.95 Dollar     <-- attendu
1.95 Dollar     <-- obtenu

-- test constructeur Argent(String) :
187.25 Euros    <-- attendu
187.25 Euros    <-- obtenu

Déposez ici le fichier Argent.java.

3.6 Exercice 7 : Ajouter et soustraire de l’Argent

Pour cet exercice, vous devez écrire les 2 méthodes public Argent plus(Argent x) et public Argent moins(Argent x), dans la classe Argent. On pourra supposer que x n’est pas null.

Pour tester les méthodes plus() et moins(), exécuter le programme Test07.java qui doit afficher :

--Test plus/moins -- redirection de sortie vers fichier Test07-sortie.txt

Maintenant, il faut vérifier que la sortie, qui a été renvoyée vers le fichier Test07-sortie.txt, est exactement identique au fichier de référence sortie07.txt. Pour ce faire on procède à la comparaison comme expliqué à la question 4.

Déposez ici le fichier Argent.java.