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.
Créez un nouveau projet dans VSCode pour ce TD.
Configurez votre projet pour l’utilisation de TC.
On aura besoin des fichiers de référence suivants que l’on
téléchargera dans le dossier racine du projet et
non pas dans le dossier src
. Veuillez bien
à télécharger directement, par clic droit sur les liens (suivi de
Save Link As
ou
Enregistrer la cible du lien sous
), plutôt que d’ouvrir ces
fichiers dans le navigateur suivi d’un copier/coller du texte vers
VSCode (cela peut poser des problèmes d’encodage et de fin de
lignes).
Vous devrez déposer votre travail au fur et à mesure. N’attendez pas la fin pour tout déposer, nous devons pouvoir suivre votre avancement.
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.
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 :
une chaine de caractères, donnant le nom de la monnaie —
ce champ, appelé nom
, sera visible de tout le programme
(public
) mais il ne pourra plus être modifié après son
initialisation (final
) ;
un nombre réel (type double
) positif donnant le
taux de conversion par rapport à l’Euro — ce champ, appelé
taux
, pourra être modifié à tout moment, mais il ne sera
accessible que de l’intérieur de la classe
(private
).
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 :
public double getTaux()
pour accéder à la valeur du
champ taux
public boolean setTaux(double autreTaux)
pour
changer sa valeur uniquement si autreTaux > 0
,
sinon ne rien faire ; le booléen renvoyé indique si l’opération de mise
à jour a réussi (true
) ou non (false
)
La classe
Monnaie
n’a pas besoin de fonctionmain
, 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
.
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
private
parce que c’est un détail d’implémentation :
les objets d’autres classes ne doivent pas l’utiliser car on devrait
pouvoir décider de passer à une autre implémentation, sans que cela
oblige à tout modifier.
final
parce qu’une fois affectée durant la
construction, la valeur et la monnaie ne changent pas.
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 classeString
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
.
Les trop jeunes pour savoir de quoi s’agit-il peuvent, en dehors des heures de cours, aller voir la source.
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 :
"."
),'s'
à partir de 2 Euros, et on écrit 1.99 Euro, de même
pour chaque monnaie).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()
etvaleurDecimale()
de la classeArgent
. Dans l’exemple, si la valeur est 12345.01, alorsvaleurEntiere()
renvoie 12345 etvaleurDecimale()
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
.
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 typeMonnaie
contient un champtaux
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 :
Vous devez voir Test04-sortie.txt
dans le répertoire
racine de votre projet (pas le répertoire
src
).
Pour comparer les deux fichiers Test04-sortie.txt
et
sortie04.txt
,
sélectionnez les deux fichiers en cliquant sur les deux, tout en
appuyant sur Ctrl
(ou ⌘ sur Mac) ;
cliquez avec le bouton droit sur l’un des deux ;
sélectionnez Compare Selected
.
Les différences entres les deux fichiers sont surlignées en couleur.
Vérifiez bien que les fichiers sont identiques!
En cas de différence, modifiez la méthode convertir
et relancez l’exécution de Test04
.
Déposez
ici le fichier Argent.java
.
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 :
Argent
, sauf lorsqu’il
s’agit de la même monnaie,convertir
,estEgalA
de
Argent
,toString
de
Argent
.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
.
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.
public static Monnaie trouverMonnaie(String s, Monnaie[] tab)
parcourt le tableau tab
par indice croissant et renvoie le
premier élément trouvé (et pas une copie) dont le champ
nom
, ou son pluriel, est égal à s
, et renvoie
null
si cet élément ne figure pas dans le tableau.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
.
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
.
public Argent(String str, Monnaie[] tab)
initialise un
objet de type Argent
à partir d’un String str
qui est dans le même format que les String
s construits par
toString()
(e.g. "18716238.99 Yuans"
).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
.
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
.
public Argent plus(Argent x)
construit et renvoie un
nouvel objet de type Argent
de même monnaie que
this
. Cette méthode opère comme suit : elle commence par
convertir x
en un xPrime
de même monnaie que
this
(on utilisera la méthode de conversion écrite en
question 4). Elle renvoie ensuite un Argent
dont la monnaie
est celle de this
et dont le montant est la somme des
montants de this
et de xPrime
.
public Argent moins(Argent x)
construit et renvoie
un nouvel objet de type Argent
de même monnaie que
this
. Puisqu’il n’y a pas d’argent négatif, la valeur de
l’argent renvoyé doit toujours être positive ou nulle.
La fonction commence par convertir x
en un
xPrime
de même monnaie que this
. Elle renvoie
ensuite un Argent
dont la valeur est la différence des
valeurs de this
et de xPrime
, seulement si
cette différence est positive ou nulle. Sinon, elle renvoie
null
pour signifier l’impossibilité de
l’opération.
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
.