Cours BUT Info

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.

Objectif des TP : construire ses premières vraies hiérarchies de classes — factorisation, extension, spécialisation — avec, pour la première fois, des classes de tests JUnit fournies qui valident chaque étape d'un coup.

TP 5 — Fond documentaire : Book, Library, ComicBook

La progression impose de poser Book seul avant d'introduire l'héritage : cote, titre, auteur, année — l'énoncé demande de réfléchir à l'accessibilité et à la visibilité de chaque attribut avant d'écrire accesseurs et mutateurs.

  1. Library gère un catalogue avec getBook(String code), addBook, removeBook surchargé (par cote ou par objet) et toString. Les affichages attendus du sujet servent de spécification, par exemple Book [H2G2:The Hitchhiker's Guide to the Galaxy->D. Adams,1979].
  2. Les emprunts ajoutent à Book un attribut borrower (0 = disponible), borrow(int borrower), giveBack() et isAvailable() ; Library délègue avec borrow(String code, int borrower), giveBack(String code) et liste les emprunts dans borrowings(). Le scénario à deux emprunteurs (42 et 404) montre l'échec d'un double emprunt.
  3. ComicBook extends Book : un attribut illustrator de plus, mais une manipulation identique à celle d'un livre — on l'ajoute au catalogue et on l'emprunte pareil. C'est tout l'intérêt de l'héritage : la bibliothèque ne change pas.
  4. Les durées créent la spécialisation : 15 jours d'emprunt pour un livre ; pour une bande dessinée, 5 jours si elle est parue il y a 2 ans ou moins, sinon 15. Un attribut borrowingDate apparaît, et getDurationMax() / getGiveBackDate() sont redéfinies dans ComicBook — le même appel sur des références Book produit des dates de retour différentes selon le type réel.

La classe de tests LibraryTest est fournie : elle rejoue tous les scénarios.

TP 5 — Inventaires : Article, Shop, PerishableArticle

Article porte une référence, un label, un prix d'achat final (non modifiable après création) et un prix de vente ; le constructeur sans prix de vente applique la marge du magasin (0.2, soit 20 %) — deuxième surcharge de constructeur du TP. getMargin() calcule la marge brute, l'affichage attendu est Article [42err404:chaise=20.0e/24.0e].

PerishableArticle extends Article ajoute une deadLine (par défaut à 10 jours de la date courante) et quatre constructeurs couvrant toutes les combinaisons de défauts. La classe Shop gère la liste d'articles, avec :

  • getPerishables() pour filtrer les périssables — une méthode support isPerishable() dans Article (fausse par défaut, vraie dans la sous-classe) évite tout instanceof ;
  • discountPerishable(LocalDate threshold, double rate) : démarque des périssables dont l'échéance arrive avant le seuil, et discountNotPerishable(double rate) pour les soldes des non-périssables ;
  • mostProfitable() : le produit le plus rentable, quelle que soit sa nature — encore un traitement générique écrit une fois sur le type parent.

La classe de tests ShopTest est fournie.

TP 6 — Salaires : une hiérarchie abstraite

La hiérarchie demandée compte 6 classes dont 2 abstraites : Employee (abstraite) → Salesperson (abstraite) → Vendor et TravellingSalesperson, plus Worker.

Le motif central est getTitle() : toString() est écrit une fois dans Employee et invoque getTitle(), redéfini partout — le nom est générique, le type d'employé est spécifique. Les commissions se factorisent dans Salesperson (20 % du chiffre d'affaires) ; les bonus deviennent des constantes : 400 € pour le vendeur, 800 € pour le représentant en raison de ses déplacements, 5 € par unité produite pour l'ouvrier.

Company gère le personnel (addEmployee, removeEmployee surchargé), compte par catégorie (getNbEmployee, getNbSalesPerson, getNbWorker) et licencie avec firing(LocalDate fatefulDate) les derniers embauchés. La variante introduit le statique : un attribut de classe objective (10 000.0 pour les commerciaux, 1 000 pour les ouvriers), une méthode objectiveFulfilled() placée là où il faut, et la surcharge firing() sans paramètre qui licencie tous les insuffisants. La classe de tests CompanyTest est fournie.

TP 6 — Revente de véhicules : masquer puis redéfinir

Car distingue les attributs constants (marque, date de première mise en circulation, prix d'achat) des variables (mise en vente, prix de vente, kilométrage) et surtout des variables de classe : temporalDropRate (0.001 par mois) et mileageDropRate (0.002 tous les 1000 km) — fixées légalement, donc identiques pour toutes les voitures, donc static. computeDropRate() cumule les deux décotes, priceEstimation() applique le taux au prix d'achat, et getSalePrice() réestime à chaque appel pour tenir compte des changements.

VintageCar extends Car masque temporalDropRate pour lui donner une valeur nulle — pas de décote temporelle sur une collection. Le scénario des deux voitures de mêmes caractéristiques fait alors le démonstrateur du cours 6 : après masquage seul, les prix restent identiques, et ce n'est qu'en redéfinissant les accesseurs des variables de classe que le calcul change enfin. La leçon : un attribut masqué ne disparaît pas, il faut aussi redéfinir les méthodes d'accès.

Dealership ferme la marche : ses méthodes de classe createCar() fabriquent une VintageCar si le véhicule a au moins 40 ans, une Car sinon, en conservant la souplesse des valeurs par défaut des constructeurs. L'utilisateur ne crée plus d'instance directement — impossible de choisir VintageCar au lieu de Car pour minimiser la décote et gonfler le prix de vente.

Redéfinir ou masquer ?

Les méthodes se redéfinissent (lookup dynamique à l'exécution) ; les attributs ne peuvent que se masquer (accès résolu par le type effectif). Le TP 6 est celui où cette distinction change le résultat à l'exécution — ne le bâclez pas.


tpOO_05.pdf

R2.01 · TP 5 — Fond documentaire / inventaires · 4 pages

Consultation seule — téléchargement désactivé

Chargement du document…

tpOO_06.pdf

R2.01 · TP 6 — Calcul de salaires / revente de véhicules · 4 pages

Consultation seule — téléchargement désactivé

Chargement du document…

Dernière mise à jour le

Sur cette page