IN101 – TP6   2010/2011
Sujet (à n’imprimer qu’une seule fois par poste de travail)

Durée : 3 h

1         OBJECTIFS

2         TRAVAIL A REALISER

Nota : le travail demandé doit être terminé, en séance ou, à défaut, hors séance.

2.1      Créer un répertoire de travail

Si BlueJ n'est pas ouvert, le lancer. Visualiser le sujet dans un navigateur pour bénéficier des liens ET en pdf pour éviter les problèmes d’affichage de certains caractères ou pour l’imprimer.        
Créer un répertoire tp6 dans In101 sur votre compte. C'est dans ce répertoire que devront être stockés tous les programmes Java et exercices relevant de ce tp.

2.2      Exercice 1 : Projet "DBShapes" (classe/méthode abstraite, interface)

Cet exercice va consister à transformer le projet DBShapes du tp4.

2.2.1      Ouvrir le projet

Télécharger le fichier DBShapesP.jar lié à cet énoncé, et l’enregistrer dans le répertoire tp6 précédemment créé.

Lancer BlueJ et ouvrir, le fichier .jar sauvegardé ci-dessus. [ Open non-BlueJ ... ].

2.2.2      Découvrir et essayer le projet DBShapesP

Ce projet correspond à peu près à ce à quoi vous deviez aboutir à la fin du TP4.

2.2.3      Restructurer ce projet

1.      Comme cela a été expliqué en cours, il n’est pas souhaitable d’autoriser l’instanciation de la classe DBShape. Faites ce qu’il faut pour cela et vérifiez que cela n’a rien changé ni à la compilation ni à l’exécution (c’est normal, il n’y avait pas d’instanciation de DBShape).

2.      Ajoutez une sous-classe Hexagone (recopiée sur Square par exemple) mais en supprimant drawSpec() car vous ne savez pas comment dessiner un hexagone pour le moment. Ajoutez un Hexagone dans Picture et rendez-le visible. Compilez. Créez une Picture : le message est cohérent, mais est-il souhaitable ?

3.      Comme cela a été expliqué en cours, il n’est pas souhaitable d’une part que les instructions de certaines méthodes soient inutiles, et d’autre part qu’une sous-classe puisse être ajoutée sans qu’elle possède les caractéristiques minimales de ses « sœurs » telles que les méthodes drawSpec() et changeSizeSpec(). Faites ce qu’il faut à ces méthodes pour corriger cela dans DBShape et recompilez Hexagone; il devrait y avoir une erreur.

4.      Pour résoudre ce problème de compilation, il faut maintenant savoir dessiner un hexagone. En s’inspirant de drawSpec() dans Triangle, de la javadoc du constructeur de Polygon, et de l’aide ci-dessous, écrivez la méthode drawSpec() dans Hexagone.   
Aide : Une façon de dessiner un hexagone est d’utiliser un Polygon avec les 6 sommets suivants : (x, y+s), (x+g, y+p), (x+g, y-p), (x, y-s), (x-g, y-p), et (x-g, y+p), avec (x, y) les coordonnées du centre, s la taille du côté, p=s/2, et g=(Ö3)s/2. (voir dessin en bas de page)
Vérifiez que l’hexagone dessiné est « régulier » et non pas « allongé ». ( Ö = racine carrée)       
Créez la classe de Test pour Hexagone et écrasez le source par celui-ci. Créez une nouvelle classe TestUtil et écrasez le source par celui-ci. Compile. Run tests. Tout est vert ? 

5.      On veut maintenant pouvoir « hériter » de plusieurs caractéristiques telles que Drawable, Measurable, … L’héritage multiple étant interdit en java, nous allons donc implanter des interfaces. Créez l’interface Drawable ne comportant que draw(), (pourquoi pas drawSpec() ?), erase(), isVisible(), makeVisible(), et makeInvisible(). DBShape doit maintenant respecter cette interface. Compilez.

6.      Créez une nouvelle interface Measurable imposant les 2 méthodes réelles surface() et perimetre(). DBShape doit maintenant respecter aussi cette interface, mais peut-elle implémenter surface()et perimetre() ? Ajouter ce qu’il faut dans les sous-classes. 
Aide : la surface d’un hexagone vaut 1.5(Ö3)s² et tous nos triangles sont forcément isocèles.
Math.hypot() peut certainement vous servir.

7.      Ajoutez dans Picture avant le deuxième System.out.println (respectivement après le dernier System.out.println) la création d’un tableau de Measurable contenant les 6 (respectivement les 3) formes existant à ce moment du programme.

8.      Ajoutez juste après chacun des 2 affichages ci-dessus un appel à la procédure (qu’il vous faudra écrire) printStats() qui devra calculer et afficher la somme des surfaces puis la somme des périmètres des formes du tableau qu’on lui passe en paramètre.   
Testez ; ça devrait donner environ 27139.08 et 1454.43, puis 6531.36 et 513.36.          
Au fait, le nombre d’instances de DBShape est-il correct, tout à la fin ?

9.      A la fin de l’exercice, on devrait se retrouver dans cette situation :

Zone de Texte: W/2Zone de Texte: W/2Zone de Texte:  HZone de Texte: x+gZone de Texte: y+sZone de Texte: y+pZone de Texte: yZone de Texte: y-pZone de Texte: y-sZone de Texte: xZone de Texte: x-gZone de Texte: 6Zone de Texte: 5Zone de Texte: 4Zone de Texte: 3Zone de Texte: 2Zone de Texte: 1

 

2.3      Exercice 2 : Les exceptions

2.3.1      Exemple simple de traitement d’exception « silencieux »

1.      Pour pouvoir observer le dessin depuis le 2.2.4.8, il faut ajouter une pause grâce à          
Thread.sleep( 5000 );  Essayez. Une erreur de compilation ?

2.      Consultez la documentation de cette méthode pour comprendre ce qui se passe, et ajoutez le try/catch nécessaire, sans rien faire en cas d’exception (à éviter en général). Recompilez et retestez.

3.      Ajoutez de même une pause avant de détruire les 3 formes.

2.3.2      Compréhension des mécanismes

Ajoutez dans un des projets BlueJ du jour une nouvelle classe FinallyDemo que vous devez copier/coller à partir de cette page.    
Compilez. Exécutez
main(). Comparez le code java et les affichages dans le terminal.

2.3.3      Création d’une classe d’expérimentation

1.      Créez une nouvelle classe Calculs sans attributs ni constructeurs.

2.      Écrivez une première méthode carre prenant une String en paramètre et devant retourner le carré du nombre représenté par la String en paramètre. Pour cela, utilisez la méthode convStringToInt qui effectue la conversion String vers entier. Incorporez le source de cette méthode à la fin de votre classe. Compilez et lisez le point suivant.

3.      Le compilateur vous dit soit de traiter l’exception « vérifiée » susceptible de se produire quand la String ne représente pas un nombre (java.util.zip.DataFormatException), soit de déclarer que la fonction carre() est susceptible de la lancer, ce qui forcera tous les programmes qui utiliseront carre() à faire de même. Pour éviter cet inconvénient, nous allons traiter l’exception dans carre(), mais le traitement consistera à lancer une exception « non vérifiée » (IllegalArgumentException) pour ne rien imposer aux utilisateurs de carre(). Il semble utile de récupérer le message d’information (grâce à la fonction getMessage()) dans l’exception que l’on a interceptée pour le transmettre au constructeur de l’exception que l’on veut lancer. Compilez. Testez avec "10" puis avec "toto" .

4.      On souhaite maintenant que la fonction retourne -1 quand son paramètre vaut "i" . Ajoutez ce cas particulier au début de la fonction. Compilez. Testez avec "i""10" et "toto" .

2.3.4      Amélioration de la classe d’expérimentation

1.      Écrivez une nouvelle méthode testCarre() sans paramètres qui commencera par déclarer un tableau de String contenant "2", "5", "i", "10", "0", "20".

2.      Affichez « 1) », calculez la somme des carrés des nombres contenus dans le tableau, puis affichez le résultat. Compilez. Testez. Cela affiche-t-il bien 1) 528 ?

3.      Affichez « 2) », copiez/collez les lignes du point 2 ci-dessus après avoir remplacé le contenu de l’avant-dernière case par "toto" . Compilez. Testez. Corrigez le problème en traitant l’exception dans la boucle. Recompilez. Retestez. Cela affiche-t-il bien 1) 528 puis 2) 528 ?

2.4      Terminer la séance

Si pas fait antérieurement, générer (après l’avoir complétée !) la documentation de ce dernier projet et de DBShapesP, puis sauvegarder les projets ouverts, puis fermer BlueJ. Si besoin, envoyer par mél à votre binôme, en fichiers attachés, tous les projets de ce tp (exportés sous forme de fichiers .jar). Se déloger.

 

Ce sujet a été élaboré par Denis Bureau.