TP noté
Ce TP sera à rendre au début de la dernière séance (semaine du 5/12). Cela vous laisse donc 4 séances de TP pour préparer ce sujet, plus le travail personnel que vous avez à fournir dans le cadre de votre formation.
Vous devrez rendre
La notation tiendra compte
Gestion d'état-civil pour une population : Classe abstraite, héritage, fichiers de données
Au cours d'un précédent TD, on a défini une collection (HashSet) d'objets de type Personne , vues du point de vue de l'état-civil. Le type général Personne a été défini comme une classe abstraite, comportant les données d"état-civil d'une personne, ainsi que des méthodes de consultation et de modification de certaines données. On a ensuite dérivé de cette classe abstraite de nouvelles classes modélisant différentes catégories de personnes.
Au cours de ce TP, on va écrire un programme d'appel permettant d'activer les diverses méthodes réalisées, pour gérer une population (collection d'objets de type Personne). Par ailleurs on verra comment mémoriser l'ensemble des données de cette collection dans un fichier de données, en vue de sa réutilisation.
I Classe abstraite Personne :
Toute personne est caractérisée par son nom, son prénom, son sexe, sa date de naissance (et éventuellement de décès), ainsi que par sa filiation. La classe Personne comporte donc les champs suivants :
nom
(String) ,Les méthodes implémentées au niveau de cette classe sont les suivantes :
- Personne (boolean sexe , Date dateNaiss , String prenom)
: constructeur initialisant les champs indiqués avec les valeurs fournies, et les autres champs avec le pointeur null ; (le nom de la personne sera en principe défini par filiation dans les classes dérivées.).- void
decedeLe (Date deces) : méthode permettant de fournir la date de décès (date qui devra être postérieure à la date de naissance, sous peine de générer une exception, impliquant l'affichage d'un message d'erreur).- String
toString ( ) : méthode fournissant une version affichable des données de l'objet actuel.- boolean
estUnFrere (Personne p) : méthode indiquant si p est un frère ou une soeur de l'objet actuel (si p est issu des mêmes parents).- boolean
estUnDemiFrere (Personne p) : méthode indiquant si p a un parent commun avec l'objet actuel.- boolean
estUnOncle (Personne p) : méthode indiquant si p est oncle ou tante de l'objet actuel (si le père de l'objet actuel est frère de p, ou si la mère de l'objet actuel est soeur de p).- boolean
estUnAncetre (Personne p) : méthode de type récursif indiquant si p fait partie des ancêtres de l'objet actuel (si p est père ou mère de l'objet actuel, ou bien si p est ancêtre du père ou de la mère de l'objet actuel).- void arbreAscendants (int indentation)
: méthode de type récursif affichant l'arbre généalogique de tous les ascendants connus de l'objet actuel avec décalages selon le niveau de parenté.Trois classes seront dérivées de cette classe abstraite, pour prendre en compte de l'évolution des données d'état-civil au cours de la vie d'une personne (classes Bébé, Enfant, et Adulte cf.. III ).
II Classes PersonSet : Ensemble de personnes dont on gère l'état-civil :
L'ensemble de personnes dont on gère l'état-civil est rassemblé dans un objet de type Collection, dont les particularités sont décrites à l'aide de méthodes supplémentaires. On définit donc la classe PersonSet comme une classe dérivée de la classe HashSet, qui ne comporte aucun champ standard supplémentaire. On y rajoute seulement les méthodes "recherchePersonne", "ajoutPersonneSaisie", "modifStatutPersonne", "verifFiliation" et " pbCreation " décrites ci-après :
- Personne recherchePersonne (String nom, String prenom)
: méthode permettant de rechercher une personne dans le HashSet, à partir de son nom et de son prénom. (L'objet retourné est le premier rencontré dans le HashSet, qui corresponde au critère de sélection.)- void ajoutPersonneSaisie ( )
: méthode permettant l'entrée au clavier des données relatives à une personne, avec vérification de la cohérence des données (existence des parents, validité de la date de naissance) avant la création effective d'un nouvel objet de type Personne (Bebe, Enfant, ou Adulte), et l'ajout de cet objet au PersonSet .- void modifStatutPersonne (Personne p , char codeModif)
: méthode permettant de modifier au clavier le type ou le statut d'une personne du PersonSet : transformation d'un type Bebe en type Enfant, d'un type Enfant en type Adulte, d'une personne mariée en personne veuve.- void verifFiliation (Personne p , Adulte mere, Adulte pere)
: méthode permettant de vérifier, à partir du PersonSet, les données de filiation concernant une personne donnée : - la mère indiquée pour la personne figure-t-elle dans le PersonSet, et s'agit-il d'une femme? - les dates de naissance sont-elles compatibles? - le père indiqué pour la personne figure-t-il dans le PersonSet, et s'agit-il d'un homme? - les dates de naissance sont-elles compatibles? En cas d'anomalie, cette méthode fait appel à la méthode pbCreation décrite ci-après, pour lever une exception du type EtatCivilException, et pour supprimer du PersonSet l'objet p anormal.- void pbCreation (String messageErreur, Personne p)
: méthode permettant de supprimer du PersonSet un objet p anormal détecté par la méthode verifFiliation ou par un modificateur, et de lever une exception du type EtatCivilException .III Classes dérivées de la classe Personne : classes Bébé, Enfant, Adulte :
a) Classe Bebe : Cette classe dérivée de Personne correspond au type basique et est instanciable. Elle possède les trois constructeurs suivants :
- Bebe (String nom , String prenom , Date dateNaiss , boolean sexe , PersonSet population) : constructeur faisant appel au constructeur de la super-classe pour initialiser les champs prenom , dateNaiss et sexe avec les valeurs fournies en paramètres, tandis que le champ nom est initialisé localement. Par ailleurs, le nouvel objet créé est ajouté au PersonSet population.
- Bebe (Adulte pere
, Adulte mere , String prenom , Date dateNaiss , boolean sexe, PersonSet population) : constructeur faisant appel au constructeur de la super-classe pour initialiser les champs prenom , dateNaiss et sexe avec les valeurs fournies en paramètres, tandis que les champs nom , pere et mere sont initialisés localement (le nom du bébé sera celui du père). Avant de créer le nouvel objet, il y a vérification de la validité des données les parents (- le père est-il un homme ? - la mère est-elle une femme ? - la date de naissance du bébé est-elle suffisamment postérieure à celle de sa mère et à celle de son père ? ). Par ailleurs, le champ "enfants" de chacun des parents du bébé est mis à jour, et le nouvel objet créé est ajouté au PersonSet "population".- Bebe (Adulte mere
, String prenom , Date dateNaiss , boolean sexe , PersonSet population) : constructeur faisant appel au constructeur de la super-classe pour initialiser les champs prenom , dateNaiss et sexe avec les valeurs fournies en paramètres, tandis que les champs nom et mere sont initialisés localement (le nom du bébé sera celui de la mère). Avant de créer le nouvel objet, il y a vérification de la validité des données concernant la mère (- la mère est-elle une femme, et la date de naissance du bébé est-elle suffisamment postérieure à celle de sa mère ? ) . Par ailleurs, le champ "enfants" de la mère du bébé est mis à jour, et le nouvel objet créé est ajouté au PersonSet" population".Les vérifications de validation des données d'état-civil peuvent générer des "exceptions" définies et gérées séparément (voir la méthode verifFiliation (personne, pere, mere) de la classe PersonSet ).
b) Classe Enfant : Cette classe dérivée de Personne comporte deux champs supplémentaires, ecole et classe correspondant à l'école fréquentée par l'enfant, et à la classe dans laquelle il se trouve. Elle comporte donc un constructeur spécifique, ayant pour 1er paramètre un objet de type Bebe :
Enfant (Bebe bb , String ecole , String classe, PersonSet population)
Ce constructeur reprend les données du bébé et fait appel au constructeur de la super-classe pour initialiser les champs correspondants, tandis que les champs ecole et classe sont initialisés localement avec les données indiquées en paramètre. . Il y ensuite suppression, dans le PersonSet population, de l'objet de type Bebe duquel on est parti, et ajout du nouvel objet de type Enfant.
Par ailleurs, la méthode toString ( ) la classe Personne, fournissant un version affichable des données de l'objet actuel, est sur-définie pour tenir compte des deux champs rajoutés.
c) Classe Adulte : Cette classe dérivée de Personne correspond à une personne pouvant avoir une profession se marier et avoir des enfants. Elle possède donc trois champs supplémentaires, profession (de type String), conjoint (de type Adulte) et enfants (de type ArrayList) .
Les méthodes implémentées au niveau de cette classe sont les suivantes :
- Adulte (Enfant e , String profession , PersonSet population)
: constructeur spécifique qui reprend les données de l'enfant e et fait appel au constructeur de la super-classe pour initialiser les champs correspondants, tandis que le champ profession est initialisé localement avec la donnée indiquée en paramètre. Il y ensuite suppression de l'objet de type Enfant duquel on est parti.- String toString (
) : sur-définition de la méthode toString de la classe Personne, pour fournir les données concernant les deux champs profession et conjoint.- void mariage (Adulte epoux
) : mise à jour de l'objet en cours, en cas de mariage, après vérification de la validité du paramètre fourni (s'agit-il d'une personne vivante du sexe opposé ?) ; cette vérification peut générer des "exceptions" définies et gérées séparément.- boolean
estVeuf ( ) : Méthode indiquant si l'objet actuel a eu un conjoint qui est décédé.- void
arbreDescendants (int indentation) : méthode de type récursif affichant l'arbre généalogique des descendants de l'objet actuel, avec décalages selon le niveau de parenté.IV Programme à réaliser :
1. Ecrire les deux méthodes statiques :
- void sauvePersonSet (PersonSet population, String nomFichier)
: sauvegarde dans un fichier binaire "nomFichier" des données contenues dans le PersonSet "population" .- void lecturePersonSet (PersonSet population, String nomFichier)
: chargement en mémoire sous la forme d'un PersonSet "population" des données contenues dans le fichier binaire "nomFichier".2. Ecrire un programme principal créant un PersonSet appelé "population", et comportant un menu, permettant de tester les opérations suivantes :
3. Compléter le programme précédent avec deux nouvelles options proposant :