TP 3-4 — Énums et encapsulation
Card et Task avec énumérations et commits GitLab, ToDoList qui grandit de 5 en 5 — puis encapsulation en cascade (Person/Student/StudentAbs/YearGroup) et réutilisation d'un jar documenté.
Objectif des TP : mettre les énumérations et l'encapsulation au service de la
réutilisation — une Task enrichie de TP en TP, une classe fournie sous forme de jar
qu'il faut savoir intégrer et lire sa documentation.
TP 3 — Cadre : dépôt GitLab et paquetage
Toutes les classes du TP vivent dans le paquetage tp03 — un paquetage par TP désormais.
Le dépôt GitLab est constitué et alimenté un commit par exercice, avec des messages
imposés : tpOO-03::exo-static, tpOO-03::exo-Task, tpOO-03::exo-ToDoList.
TP 3 — Card et LocalDate
Les enums Color (CLUB, DIAMOND, HEART, SPADE) et Rank (SEVEN à ACE) sont fournies
dans l'énoncé. Card les combine et impose une surcharge de constructeur :
public Card(Color color, Rank rank) { /* ... */ }
public Card(String color, String rank) { /* via valueOf */ }La classe UseCard fournie valide equals. L'exploration de LocalDate passe par la
javadoc : distinguer les méthodes statiques (now, of) des méthodes d'instance,
comparer deux dates chronologiquement, ajouter une durée (plusDays), calculer un écart
avec until et l'enum ChronoUnit (paquetage java.time.temporal), créer une date
aléatoire dans les 30 dernières années.
TP 3 — Task : statuts et numéro automatique
Task rejoue le compteur d'instances du cours 3 : idTask est un numéro automatique.
Les deux constructeurs fixent les valeurs par défaut — créée à la date du jour, échéance
à 10 jours plus tard, statut initial TODO — seul le couple (description, durée) est
essentiel ; le constructeur long prend création, échéance et durée. L'affichage attendu
est T<id> = <description>:<status>(<duration>):<deadline>.
L'enum TaskStatus (TODO, ONGOING, DELAYED, FINISHED) donne tout son intérêt à
changeStatus() sans paramètre : passer au statut suivant dans l'ordre de
déclaration se calcule avec ordinal() et values(). La surcharge
changeStatus(TaskStatus) force un statut précis. Deux méthodes complètent la classe :
isLate(), qui ne doit jamais renvoyer true pour une tâche achevée (tester le
statut avant la date), et delay(int nbDays), qui repousse l'échéance.
L'exercice complémentaire ToDoList stocke les tâches dans un tableau initial de 5
cases, agrandi de 5 en 5 (enlarge) : ajout en première case libre, suppression par
null — les tâches ne sont donc pas forcément contiguës. S'y ajoutent getNbTask,
isOverwhelmed, dueTasks (échéances du jour), onSickLeave (report global) et trois
tris : ancienneté, urgence, durée.
TP 4 — Encapsulation en cascade
L'exercice 1 empile trois encapsulations successives, chacune sans modifier la classe encapsulée :
Person: identifiant automatique, prénom, nom ; accesseurs et mutateurs — sauf sur l'ID, immuable ;toStringsous la forme<id>: <forename> <name>etequalspar identifiant seul, quel que soit le nom. La classe de testUsePersonest fournie sous Moodle.Studentencapsule unPersonprivé plus un tableau de notes sans case vide. Des trois constructeurs demandés, celui qui reçoit unPersonen paramètre doit passerprivate: il exposerait l'objet encapsulé à l'extérieur. Viennent ensuite les méthodes déléguées, unequalssur tous les champs (en déléguant àPerson.equalset en s'aidant de la boîte à outilsArrays),getAverage(0 sans note) etaddGradeavec réallocation du tableau.StudentAbsencapsule leStudentplus un nombre d'absences ;toStrings'appuie sur letoStringde l'étudiant,equalssur sonequals. Les seuils font la différence :warning(thresholdAbs, thresholdAvg)déclenche si absences ≥ seuil ou moyenne ≤ seuil,validationexige strictement moins d'absences et strictement mieux en moyenne — lire les signes au mot près.YearGroupagrège une liste deStudentAbs— et l'énoncé le signale : ce n'est plus de l'encapsulation, juste une association.addStudent(unitaire et en liste),addGrades(double[])qui répartit les notes dans l'ordre des étudiants, etvalidation(int, int)qui affiche les validés.
TP 4 — Un jar fourni : PendingCaseQueue
L'exercice 2 réutilise l'archive tp04-res.jar, qui contient la classe compilée
PendingCase (paquetage tpOO.tp04), documentée par la javadoc de tp04-doc.zip à
ouvrir via index.html. Lire la documentation avant d'écrire le code : c'est une
partie de l'exercice.
PendingCaseQueue encapsule un tableau initialisé à null, une capacité commune à
toutes les instances (10 par défaut, donc static) et un indice idx pointant la
prochaine insertion. Ajouter décale idx vers la droite ; retirer décale tous les
éléments restants vers la gauche et ramène idx d'un cran — le schéma de l'énoncé
(file de capacité 4, retrait puis ajout) mérite d'être reproduit à la main avant de
coder. Les méthodes se déduisent du modèle : clear, isEmpty/isFull, size,
addOne, removeOne (renvoie null si la file est vide — l'énoncé conseille de
décomposer le code), toString dans l'ordre, getTotalAmount, et la facétieuse
cheating(PendingCase, position) qui insère à une place donnée pour passer avant tout le
monde — à condition que la file ne soit pas pleine. La classe UsePendingCaseQueue
fournie teste les cas limites (file de capacité 3, 4 dossiers en attente).
Le réflexe du semestre
Chaque classe écrite ici est pensée pour être réutilisée par la suivante : la Task du
TP 3 revient en R2.03, et PendingCaseQueue montre comment consommer une classe dont on
n'a que le binaire et la documentation.
Parce qu'il met la classe encapsulée dans la signature publique : n'importe quel
client pourrait conserver la référence Person reçue et la modifier derrière le dos
du Student. L'encapsulation impose que le Person soit créé et détenu en interne.
Avec ordinal() et values() : la position actuelle plus un, modulo la taille du
tableau des valeurs — la même mécanique que la saison suivante du cours 3.
L'énoncé la définit « commune à toutes les instances » : une constante de classe
(static final, valeur 10) documente la règle en un seul endroit au lieu de la
recopier dans chaque constructeur.
Elle insère un dossier à la position demandée en décalant les suivants, au lieu de le
placer en fin de file — pour qu'il soit traité plus vite. Elle n'est possible que si
la file n'est pas pleine : vérifier isFull avant de décaler.
tpOO_03.pdf
R2.01 · TP 3 — Énumérations et méthodes statiques · 3 pages
Chargement du document…
tpOO_04.pdf
R2.01 · TP 4 — Encapsulation pour l'extension / contrôle d'accès · 4 pages
Chargement du document…
Dernière mise à jour le
TP 1-2 — Bases et références
Écrire ses premières classes Java en compilant au terminal : Book et un HighScore trié, structure irrégulière, puis concurrents de roller et jeu de dés — la démarche exercice par exercice.
TP 5-6 — Héritage et hiérarchies
Construire ses premières hiérarchies de classes avec des tests JUnit fournis : bibliothèque et articles périssables, puis salaires d'une entreprise et revente de véhicules de collection.