Vous êtes sur la page 1sur 4

Universite Paris Diderot

L3 Informatique

Programmation Orientee Objet


Annee 2008-2009

TP n6
Interfaces, polymorphisme
Un document sur Javadoc vous est fournit. Prenez le temps de le lire et documentez votre code
au format Javadoc.

Premi`
ere partie : Formateur de texte sans justification
Le but du TD sera de realiser un formateur de texte fonctionnant sur le meme principe que le
formateur de texte fmt sous Unix.
` laide dun objet de la classe Scanner, on lit des mots un `a un. Un deuxi`eme objet, le formateur,
A
accumule ces mots en listes de lignes dont chacune contient des mots separes par des espaces.
Le formateur imprime ensuite la liste de ces lignes. Ainsi, le programme supprime les espaces
redondants entre deux mots, les lignes vides redondantes entre deux paragraphes, ou les passages
`a la ligne non necessaires. En option, le formateur est capable de justifier du texte.
On modelise le probl`eme de la facon suivante : on introduit le concept de Bote qui represente
les objets composant le texte formate.
une Bote est un element du texte formate qui a une taille et peut etre affiche.
une Bote espace est un element du texte formate qui separera les mots. Ce sera un seul espace
dans le cas ou le texte nest pas justifie, et potentiellement plusieurs espaces sinon.
une Bote mot est un element du texte formate qui representera un mot.
une Bote composite representera une ligne de texte.
le Formateur utilise la classe Scanner et les classes et interfaces precedemment decrites pour
construire le texte formate.
Les objets implementant linterface Boite representeront une unite de texte dau plus une ligne,
soit un mot, un espace, ou une ligne. Trois classes implementeront cette interface :
BoiteEspace : un objet de cette classe represente un espace ;
BoiteMot : un objet de cette classe represente un mot ;
BoiteComposite : un objet de cette classe represente une suite horizontale de botes ; nous
nous en servirons pour representer les lignes.
Exercice 1

Ecrivez
la declaration de linterface Boite, qui contient les declarations de deux methodes publiques : length(), de type entier, toString(), de type String.
Exercice 2

Ecrivez
ensuite les definitions de deux classes qui implementent cette interface : BoiteEspace et
BoiteMot. Une BoiteEspace a une longueur de 1, et se convertit en la chane reduite `a un espace
" " (`a ne pas confondre avec la chane vide !). Une BoiteMot represente une chane arbitraire,
sa methode toString retourne cette chane, et la methode length() retourne sa longueur.
Exercice 3

Ecrivez
maintenant une nouvelle classe BoiteComposite qui implemente linterface Boite. Une
1

bote composite contient une suite de botes ; sa largeur est la somme des largeurs des botes
quelle contient, et sa representation sous forme de chane est la concatenation des representations
des botes quelle contient.
Remarque : Les objets de la classe BoiteComposite stockent des objets qui sont soit des mots,
soit des espaces, soit eux-memes des botes composites. Reflechissez soigneusement au type de
structure quil faut utiliser.
En plus des methodes de linterface Boite, la classe BoiteComposite implemente une methode
publique isEmpty qui determine si une bote composite est vide, et une methode publique
addBoite qui ajoute une bote `
a la fin dune bote composite. Il est peut-etre judicieux dajouter
des methodes auxiliaires privees.
Exercice 4

Ecrivez
maintenant une classe Formateur qui accumule la suite des mots contenus dans un fichier
texte. Le constructeur de cette classe prendra un nom de fichier sur lequel il construira un objet
de la classe Scanner, le parseur.
Decrivez les deux methodes publiques : read, qui lit la suite des mots retournes par le parseur
et la range dans un vecteur de Boite, et print, qui imprime cette suite de mots. Le vecteur
de Boite est organise comme suit. Tous les mots dun paragraphe sont accumules dans une
BoiteComposite. Le formateur commence la lecture avec une bote composite vide. A chaque
fois quil lit un nouveau mot, il y ajoute un espace et la bote representant ce mot. Enfin, lors
dune fin de paragraphe, cest-`
a-dire quand il trouve une ligne vide, il ajoute la bote courante
au vecteur de Boite et recommence avec une nouvelle bote composite vide. Il sera peut-etre
judicieux dutiliser une methode privee pour la fin dun paragraphe.
Pour pouvoir reconnatre la fin dun paragraphe, la methode read pourrait utiliser un autre objet
de la classe Scanner. Vous pouvez aussi etudier la methode useDelimiter, et les variantes de
la methode hasNext.
Vous ferez attention `
a najouter despaces ni au debut ni `a la fin dun paragraphe.
Exercice 5
Modifiez le programme precedent pour quil coupe les lignes. Le formateur passe maintenant `
a
une nouvelle bote composite d`es lors quajouter le nouveau mot `a la bote courante lui ferait
depasser la largeur de la page (fixee arbitrairement, par exemple `a 75). Cependant, on ne passe
jamais `a une nouvelle bote si la bote courante est vide (pourquoi ?).
Pour des raisons esthetiques, le programme devra inserer une ligne blanche entre deux paragraphes.
Exercice 6

Ecrivez
une classe Test pour tester votre programme.

Deuxi`
eme partie : Formateur de texte avec justification
Le texte produit dans le formateur realise nest pas justifie puisque la marge droite nest pas
alignee. Pour justifier le texte, nous introduisons une nouvelle interface BoiteEtirable qui etend
linterface Boite. Les objets de linterface BoiteEtirable pourront etre convertis en chanes de
longueur arbitraire, ce qui nous permettra de justifier les lignes.
Afin de produire du texte justifie, on modifie la methode dimpression de la classe Formateur
pour quelle imprime des espaces de largeur variable.
Exercice 7
Commencez par ajouter `
a linterface Boite une nouvelle methode booleenne isEtirable, et
ecrivez le code de cette methode pour toutes les classes qui implementent Boite. Pour le moment,
cette methode retourne false pour tous les objets.
Exercice 8
Definissez maintenant une nouvelle interface BoiteEtirable qui etend Boite en lui ajoutant une
methode toString(int n) de type String. Dans le reste de cette partie, vous implementerez
cette nouvelle methode qui doit convertir une bote en une chane, mais en ajoutant n espaces
supplementaires aux endroits o`
u cela peut se faire.
Exercice 9
Modifiez maintenant la definition de la classe BoiteEspace pour quelle implemente linterface
BoiteEtirable. Toutes les BoiteEspaces sont etirables (la methode isEtirable retourne toujours true), et toString(n) retourne simplement une chane de n+1 espaces (lespace dorigine,
et n espaces ajoutes).
Exercice 10
Le cas dune bote composite est un peu plus complique. Une bote composite peut-etre etiree
d`es quune des botes quelle contient peut letre : la methode isEtirable devra donc verifier
si cest le cas.
La methode toString(n) devra ajouter un certain nombre despaces `a chaque bote etirable
contenue. Malheureusement, ce nombre nest pas toujours constant : si une bote composite
contient deux botes etirables et quil faut distribuer trois espaces, il faudra ajouter deux espaces
`a la premi`ere mais un seul `
a la seconde.
Supposons quune bote composite contienne e botes etirables et quon veuille letirer de n
espaces, le nombre exact despaces `
a ajouter `a chaque bote etirable contenue est alors nesp = ne .
Cependant, n peut tr`es bien ne pas etre divisible par e ; on calcule donc nmin = [nesp ], la partie
enti`ere de nesp , qui est le nombre minimal despaces `a rajouter `a une bote etirable. Le nombre
despaces qui nous restent est alors nsuppl = n e nmin .
La methode toString(n) de la classe BoiteComposite devra donc calculer les entiers nmin et
nsuppl comme ci-dessus, et ensuite retourner la concatenation de ses elements ; les nsuppl premiers
elements etirables devront etre etires de nmin + 1 espaces, tandis que les autres devront letre de
nmin espaces seulement.
Exercice 11

Ecrivez
la methode print de la classe Formateur pour quelle etire les lignes etirables1 afin
darriver `a une largeur uniforme de 75 caract`eres.
1

Pourquoi certaines lignes risquent-elles de ne pas etre etirables ?

Exercice 12
Le programme precedent a un defaut flagrant : il justifie toutes les lignes, meme celles qui sont `
a
la fin dun paragraphe. Il va donc falloir le modifier pour inhiber la justification de ces derni`eres.
On pourrait penser `
a definir une nouvelle classe qui ressemble `a BoiteComposite mais dont les
objets ne sont jamais etirables. Cependant, Java noffre pas de facilites pour changer la classe
dun objet apr`es sa creation, donc on naurait aucun moyen de changer la classe de la bote
courante au moment darriver `
a la fin du paragraphe.
La solution retenue consiste `
a inclure dans la classe BoiteComposite un nouveau champ booleen
inhibe qui sert `
a inhiber letirage. Ajoutez une nouvelle methode inhibeEtirage() qui fixe ce
champ `a true et une methode setEtirable(boolean b) qui affecte b `a ce champ. Modifiez
egalement la methode isEtirable pour prendre en compte le champ inhibe.
Exercice 13
Implementez la gestion des lignes en fin de paragraphe dans la classe Formateur.