Master 2 BBSG
2. Objets
POO, langage Java
Laurent Tichit
1. Les articles du supermarch
2. Dates
3. Flacons et bouteilles...
4. Points du plan
5. Objets membres dautres objets
6. Fractions
2.1. Les articles du supermarch
A. crivez une classe Article pour repr senter les articles vendus dans un supermarch . Chacun
comporte quatre variables dinstance
" private long reference un num ro qui caract rise larticle de mani re unique
" private String intitule la description de larticle sous forme de texte
" private float prixHT le prix unitaire hors taxes de larticle
" private int quantiteEnStock le nombre dunit s de larticle disponibles
et dispose dun certain nombre de m thodes
" public Article(long reference, String intitule, float prixHT, int
quantiteEnStock) constructeur imm diat qui donne une valeur chacune des variables
dinstance,
" public long getReference(), public String getIntitule(), public int
getQuantiteEnStock() les accesseurs permettant dobtenir la valeur de chaque
variable dinstance
" public void approvisionner(int nombreUnites) m thode pour augmenter la
quantit disponible de larticle
" public boolean vendre(int nombreUnites) cette m thode enregistre la vente
dun certain nombre dunit s de larticle, dont il faut donc diminuer en cons quence la quantit
disponible en stock.
Si nombreUnites est sup rieur la quantit disponible alors le stock nest pas modifi et la
m thode renvoie false ; autrement elle renvoie true.
" public float prixHT() cette m thode calcule et renvoie le prix HT de larticle
" public float prixTTC() cette m thode calcule et renvoie le prix TTC de larticle
" public String toString() cha ne de caract res exprimant la r f rence, lintitul et le
prix de larticle.
" public boolean equals(Article unArticle) a.equals(b) est true si et
seulement si a et b repr sentent le m me article (cest- -dire sils ont la m me r f rence).
B. Pour tester cette classe crivez une m thode main qui cr e un tableau comportant trois articles (au
moins) et qui essaie toutes ces m thodes.
N.B. Attention, la m thode equals officielle na pas exactement len-t te que nous avons utilis ici
(on verra cela plus loin).
2.2. Dates
Pour cet exercice faites semblant de ne pas savoir quil existe dans la biblioth que Java des
classes java.util.Date et java.util.Calendar qui offrent probablement les
services demand s ici.
crivez une classe Date dont chaque instance repr sente une date pr cise. Mettez-y quatre variables
dinstance priv es : annee (un entier non n gatif), mois (un entier compris entre 1 et 12), jour (un
entier compris entre 1 et une borne sup rieure qui d pend du mois) et jourSemaine (un entier
indiquant le jour de la semaine : 0 pour lundi, 1 pour mardi, etc.
crivez les m thodes
" public Date(int jour, int mois, int annee) initialisation dune date, partir
des trois nombres donn s. La validit des ces nombres doit tre v rifi e (voyez ci-dessous
Publicité
comment) et, en cas de date incoh rente, un message doit tre affich et le programme abandonn .
Cest ici que le jour de la semaine doit tre d termin (voyez ci-dessous une mani re simple de le
faire).
" int getJour(), int getMois(), int getAnnee(), int getJourSemaine()
des accesseurs pour obtenir les valeurs correspondantes
" public String toString() renvoie lexpression dune date sous forme de texte, comme
"vendredi 8 d cembre 2006"
" public boolean infeg(Date d) comparaison : a.infeg(b) renvoie true si la date
a est ant rieure ou gale la date b, sinon cela renvoie false.
Pour simplifier, supposez quune ann e est bissextile si et seulement si son mill sime est divisible par
quatre (en r alit cest un peu plus compliqu ).
Indications, 1 Pour abandonner le programme vous pouvez appeler la m thode System.exit(int
code). Un tel traitement des erreurs est na f, nous verrons plus loin ( loccasion des exceptions) une
meilleure mani re de faire cela.
Indications, 2 Pour vous viter de perdre votre temps sur des choses qui ne sont pas lobjet de cet
exercice, voici une expression valuant la validit dune date (avec la simplication sur les ann es
bissextiles mentionn e). Vous pouvez vous contenter de la copier-coller dans votre programme, puis de
tester la valeur de dateInvalide :
boolean dateInvalide = mois < 1 || mois > 12
|| jour < 0 || jour > 31
|| jour == 31 && (mois == 4 || mois == 6 || mois == 9 || mois == 11)
|| jour >= 30 && mois == 2
|| jour == 29 && mois == 2 && annee % 4 != 0;
Indications, 3 Pour vous viter de perdre votre temps sur des choses qui ne sont pas lobjet de cet
exercice, voici une mani re simple de calculer le jour de la semaine correspondant une date donn e (en
trichant un peu par rapport notre engagement de ne pas utiliser les outils de la biblioth que Java) :
private int jourSemaine(int jour, int mois, int annee) {
Calendar c = Calendar.getInstance();
c.set(annee, mois - 1, jour);
return c.get(Calendar.DAY_OF_WEEK);
}
crit comme cela, vous obtenez 1 : dimanche, 2 : lundi, ... 7 : samedi. Pour avoir 0 : lundi, 1 : mardi, ...
6 : dimanche, remplacez la derni re ligne ci-dessus, par :
return (c.get(java.util.Calendar.DAY_OF_WEEK) + 5) % 7;
Attention vos ventuels import : un malencontreux import java.util.*; va cr er un conflit
muet entre java.util.Date et votre propre Date. En r gle g n rale, vitez asolument les import
du style import monPackage.*;
2.3. Flacons et bouteilles...
Vous travaillez chez Bobard & Co., producteur exclusif du sirop Mirifik, un lixir extraordinaire issu de la
recherche spatiale qui rend jeune, beau et intelligent et qui emp che la chute des cheveux et les t ches de
transpiration. Dilu diff rentes concentrations, le sirop Mirifik est commercialis dans diverses sortes de
flacons.
On vous demande d crire une classe Flacon dont les instances repr sentent les flacons de sirop Mirifik
en stock. Cette classe comportera :
" des variables dinstance :
" private final float capacite la capacit du flacon (en ml) ,
" private float volume le volume de liquide (en ml) que le flacon contient un
instant donn ,
" private float concentration la concentration de ce liquide, c.- -d. le rapport
(volume sirop) / (volume sirop+eau),
" String etiquette un texte libre affich sur le flacon
" des m thodes :
Publicité
" public Flacon(String etiquette, float capacite) Construction dun
flacon ayant la capacit donn e et portant l tiquette indiqu e. Initialement, le volume est
mis z ro.
" public void verser(float volumeSirop, float volumeEau) Ajout
un flacon des volumes de sirop et deau indiqu s.
La possibilit dune telle op ration doit tre v rifi e et, en cas dimpossibilit , on doit
produire laffichage dun message et labandon du programme.
" public void transvaser(Flacon autreFlacon, float volume)
Ajout un flacon du volume indiqu du liquide extrait de lautreFlacon indiqu .
La possibilit dune telle op ration doit tre v rifi e et, en cas dimpossibilit , on doit
produire laffichage dun message et labandon du programme.
" public String toString() Affichage de l tiquette, du volume et de la
concentration du contenu du flacon en question.
crire une m thode main pour tester toutes ces op rations.
Que pensez-vous des qualifieurs que nous avons appliqu aux variables dinstance ? Pourquoi
capacite a t qualifi e final ? Est-il int ressant de qualifier private le volume et la
concentration ?
N.B. Comme lexercice pr c dent, pour abandonner le programme vous pouvez appeler la m thode
System.exit(int code).
2.4. Points du plan
A. D finissez une classe Point pour repr senter les points du plan rapport une origine fix e. Les
coordonn es dun point sont ici deux nombres flottants x, y, m moris s dans deux variables dinstance
priv es (par exemple de type double). La classe Point comportera au moins les m thodes dinstance
suivantes, toutes publiques :
" Point(double x, double y), constructeur dun point partir
de ses coordonn es cart siennes,
" double x(), double y() qui renvoient les coordonn es
cart siennes du point,
" double r(), double t(), qui renvoient les coordonn es polaires
du point (voir ci-dessous),
" String toString(), qui renvoie une expression textuelle du
point, comme "(2.0,3.0)",
" boolean equals(Object o), comparaison : a.equals(b)
r pond la question a et b repr sentent-ils deux points gaux ? ,
" void homothetie(double k), qui applique au point une
homoth tie de centre (0, 0) et de rapport k ; pour cela, il suffit de
remplacer (x, y) par (k x, k y),
" void translation(double dx, double dy), qui applique
au point une translation de vecteur (dx, dy) ; cela consiste remplacer
(x, y) par (x + dx, y + dy).
" void rotation(double a), qui applique au point une rotation
de centre (0, 0) et dangle a.
Une mani re qui nest pas la plus efficace de faire cela consiste
calculer les coordonn es polaires (r, t) correspondant (x, y) puis les
coordonn es cart siennes (x, y) correspondant (r, t + a)
Rappel de formules: x = r cos(t), y = r sin(t), r = sqrt(x2 + y2), t = atan(y / x)
B. Application de la classe Point. Une ligne polygonale est d finie par un certain nombre de points, ses
sommets. D finissez une classe LignePol pour repr senter de tels objets. Les sommets y seront
m moris s sous forme de tableau de points. Il en d coule que le nombre de sommets dune ligne
polygonale ne pourra pas augmenter au cours de la vie de celle-ci, mais cela ne sera pas un probl me dans
le cadre de cet exercice.
Cette classe comportera au moins deux variables dinstance priv es :
Publicité
" Point[] sommets le tableau des points qui sont les sommets de la ligne polygonale,
" int nbSommets le nombre de sommets (ici, cette information est redondante, puisque
nbSommets = sommets.length)
et les m thodes publiques :
" LignePol(int n), constructeur dune ligne polygonale n
sommets (initialement ind termin s),
" LignePol(Point[] sommets), constructeur dune ligne
polygonale ayant les sommets indiqu s,
" Point getSommet(int i), renvoie le i me sommet,
" void setSommet(int i, Point p), donne p pour valeur
du i me sommet,
" String toString(), renvoie une expression de la ligne
polygonale sous forme de texte,
" void homothetie(double k), qui applique chaque
sommet de la ligne polygonale une homoth tie de centre (0, 0) et de
rapport k,
" void translation(double dx, double dy), qui
applique chaque sommet de la ligne polygonale une translation de
vecteur (dx, dy)
" void rotation(double a), qui applique chaque sommet
de la ligne polygonale une rotation de centre (0, 0) et dangle a
En supposant (cest tout fait fictif) que vous disposiez dun environnement graphique dans lequel on
obtient le trac du dextr mit s (x0,y0) et (x1,y1) par lexpression
tracerLigne(int x0, int y0, int x1, int y1)
ajoutez la classe LignePol une m thode tracer qui produit le trac de la ligne polygonale. Ensuite,
crivez une m thode main qui construit et trace la cocotte ci-dessus.
N.B. Pour faire tourner la simulation vous pouvez d finir :
void tracerLigne(int x0, int y0, int x1, int y1) {
System.out.println("tracer de (" + x0 + "," + y0 + ") (" + x1 + "," +
y1 + ")");
}
C. Imaginons (cest de la fiction) quune enqu te effectu e aupr s des utilisateurs de votre classe Point
a montr que cette classe est correcte et pratique mais que, du point de vue des performances, il aurait
mieux valu prendre pour repr sentation interne des points leur coordonn es polaires (r, t) au lieu des
coordonn es cart siennes (x, y).
R crivez donc la classe Point de mani re que les variables dinstance soient les coordonn es polaires
du point, et non plus ses coordonn es cart siennes, en respectant la contrainte suivante :
Vous devez faire en sorte que la vue publique de la classe soit inchang e, afin que les
applications de la classe Point (par exemple, la classe LignePol) restent valides sans
n cessiter la moindre modification. Une confirmation quon a respect cette contrainte sera
que le programme de la question pr c dente fonctionne sans quil y ait besoin de modifier
quoi que ce soit.
2.5 Objets membres dautres objets
Cet exercice est surtout une petite r flexion sur la notion de duplication ou clonage dobjets, surtout
quand il sagit dobjets qui ont pour membres dautres objets (ce qui est le cas de la majorit des objets).
Vous devez disposer dune classe Point, m me tr s simple (par exemple, celle du d but de lexercice
pr c dent). Assurez-vous que cette classe na pas de constructeur sans arguments.
A. Un rectangle est d termin par la donn e de deux points, respectivement son angle sup rieur gauche et
son angle inf rieur droit. D finissez une classe Rectangle ayant deux variables dinstance priv es
coinNO (pour coin Nord-Ouest ) et coinSE (pour coin Sud-Est ) et, au moins, les m thodes
suivantes :
" Rectangle(double x0, double y0, double x1, double y1), constructeur dun
Publicité
rectangle ayant (x0,y0) et (x1,y1) pour coins,
" String toString(), qui renvoie une expression du rectangle sous forme de texte, comme
"[(1.0,2.0);(3.0,4.0)]",
B. Faites le test suivant :
public static void main(String[] args) {
Rectangle r1, r2;
r1 = new Rectangle(1, 2, 3, 4);
r2 = r1;
System.out.println("r1: " + r1 + ", r2: " + r2);
r1.coinNO = new Point(0, 0);
System.out.println("r1: " + r1 + ", r2: " + r2);
r1.coinSE.homothetie(2);
System.out.println("r1: " + r1 + ", r2: " + r2);
}
On aurait pu penser que lexpression r2 = r1; affectait r2 une duplication de r1. Quest-ce que
lex cution du code pr c dent montre ?
C. crivez la premi re ligne de la classe Rectangle comme ceci
public class Rectangle implements Cloneable {
et len-t te de la fonction main comme ceci
public static void main(String[] args) throws CloneNotSupportedException {
Maintenant remplacez la ligne r2 = r1; par
r2 = (Rectangle) r1.clone();
Votre classe utilise donc maintenant la version pr d finie de la m thode clone. Reex cutez le test :
quest-ce que vous constatez ?
D. Ajoutez votre classe la m thode suivante (vous pouvez effacer ou non les d clarations
implements :
public Rectangle clone() {
return new Rectangle(coinNO.x(), coinNO.y(), coinSE.x(), coinSE.y());
}
et refaites le test. Que constatez-vous pr sent ?
2.6 Fractions
La biblioth que Java ne comporte pas de classe pour repr senter les fractions (comme celles de l cole
primaire, avec un num rateur et un d nominateur). On se propose ici de pallier ce manque, en d finissant
une classe Fraction munie des m thodes suivantes :
" public Fraction(BigInteger num, BigInteger den) constructeur basique
" public Fraction(int n, int d) construction dune fraction partir de deux entiers
(quil faudra convertir en BigInteger)
" public Fraction(int n) construction dune fraction partir dun entier (pour
transformer un entier en fraction on met 1 comme d nominateur)
" public Fraction add(Fraction f) addition de deux fractions
" public Fraction sub(Fraction f) soustraction de fractions
" public Fraction mult(Fraction f) multiplication de fractions
" public Fraction divi(Fraction f) division de fractions
" public String toString() conversion dune fraction en cha ne de caract res
" public double doubleValue() obtention dune valeur d cimale qui est une
approximation de la fraction
C'est pour viter les probl mes de d bordement qu'il est conseill de repr senter le num rateur et le
d nominateur dune fraction par des objets BigInteger.