Exercice 23 || Solution
Partie 1 : Création de la classe de base Animal
Créez une classe Python nommée Animal qui servira de classe mère. Cette classe doit posséder les trois attributs suivants :
- nom : une chaîne de caractères représentant le nom de l'animal.
- age : un nombre entier représentant l'âge de l'animal en années.
- espece : une chaîne de caractères indiquant l'espèce de l'animal (exemple : "Mammifère", "Oiseau", etc.).
La classe Animal doit inclure :
- Une méthode spéciale __init__(self, nom, age, espece) pour initialiser les trois attributs lors de la création d'un objet.
- Une méthode d'instance afficher_infos(self) qui affiche (avec print) les valeurs des attributs nom, age et espece dans un format clair et lisible.
Partie 2 : Héritage - Création de la classe Chien
Créez maintenant une nouvelle classe nommée Chien qui hérite de la classe Animal.
- La classe Chien doit ajouter un attribut supplémentaire propre à elle :
- race : une chaîne de caractères spécifiant la race du chien (exemple : "Labrador", "Berger Allemand").
- Définissez le constructeur __init__(self, nom, age, espece, race) pour la classe Chien. Dans ce constructeur, vous devez appeler explicitement le constructeur de la classe mère (Animal) pour initialiser les attributs hérités (nom, age, espece), puis initialiser le nouvel attribut race.
- Ajoutez une méthode afficher_race(self) qui affiche la race du chien.
Partie 3 : Encapsulation - Getters et Setters
Afin de bien encapsuler les données et de contrôler l'accès aux attributs, vous allez implémenter des accesseurs (getters) et des mutateurs (setters) pour tous les attributs (y compris ceux hérités) de la classe Chien.
Pour chaque attribut (nom, age, espece, race), vous devez créer :
- Une méthode getter (exemple : get_nom(self)) qui retourne la valeur de l'attribut.
- Une méthode setter (exemple : set_nom(self, nouvelle_valeur)) qui permet de modifier la valeur de l'attribut.
Partie 4 : Test du programme
Dans la partie principale de votre script (if __name__ == "__main__":), testez l'ensemble de vos classes en suivant ces étapes :
- Instanciation : Créez un objet de la classe Chien en fournissant des valeurs initiales pour son nom, son âge, son espèce et sa race.
- Affichage initial : Utilisez les méthodes afficher_infos() et afficher_race() pour afficher toutes les informations de ce chien.
- Modification : Utilisez les setters que vous avez créés pour :
- Modifier l'âge du chien.
- Modifier la race du chien.
- Affichage final : Affichez à nouveau les informations complètes du chien (en utilisant afficher_infos() et afficher_race()) pour vérifier que les modifications ont bien été prises en compte.
Solution
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
""" Exercice 23: TP — Programmation Orientée Objet : Héritage et Encapsulation Solution complète avec explications détaillées """ # ============================================ # PARTIE 1 : CLASSE DE BASE Animal # ============================================ class Animal: """ Classe de base représentant un animal générique. Cette classe sert de modèle pour tous les animaux. """ def __init__(self, nom: str, age: int, espece: str): #Constructeur de la classe Animal. # Initialisation des attributs avec les valeurs passées en paramètres # Le caractère "_" indique que c'est un attribut "protégé" self._nom = nom self._age = age self._espece = espece def afficher_infos(self): """ Méthode qui affiche toutes les informations de l'animal. C'est une méthode d'instance qui utilise les attributs de l'objet. """ print(f"Nom: {self._nom}") print(f"Âge: {self._age} ans") print(f"Espèce: {self._espece}") # ============================================ # GETTERS ET SETTERS pour la classe Animal # ============================================ # GETTER pour l'attribut nom def get_nom(self): """ Getter pour l'attribut nom. Retourne la valeur actuelle du nom. """ return self._nom # SETTER pour l'attribut nom def set_nom(self, nouveau_nom: str): """ Setter pour l'attribut nom. Modifie la valeur du nom avec la nouvelle valeur. """ self._nom = nouveau_nom # GETTER pour l'attribut age def get_age(self): """ Getter pour l'attribut age. Retourne la valeur actuelle de l'âge. """ return self._age # SETTER pour l'attribut age def set_age(self, nouvel_age: int): """ Setter pour l'attribut age. Modifie la valeur de l'âge avec la nouvelle valeur. """ self._age = nouvel_age # GETTER pour l'attribut espece def get_espece(self): """ Getter pour l'attribut espece. Retourne la valeur actuelle de l'espèce. """ return self._espece # SETTER pour l'attribut espece def set_espece(self, nouvelle_espece: str): """ Setter pour l'attribut espece. Modifie la valeur de l'espèce avec la nouvelle valeur. """ self._espece = nouvelle_espece # ============================================ # PARTIE 2 : CLASSE Chien (héritant de Animal) # ============================================ class Chien(Animal): """ Classe Chien qui hérite de la classe Animal. Cette classe représente un type spécifique d'animal. """ def __init__(self, nom: str, age: int, espece: str, race: str): """ Constructeur de la classe Chien. Appelle d'abord le constructeur de la classe parent (Animal) puis initialise l'attribut spécifique à Chien. """ # Appel du constructeur de la classe parent (Animal) # super() permet d'accéder aux méthodes de la classe parent super().__init__(nom, age, espece) # Initialisation de l'attribut spécifique à la classe Chien self._race = race def afficher_race(self): """ Méthode spécifique à la classe Chien. Affiche uniquement la race du chien. """ print(f"Race: {self._race}") # ============================================ # GETTER ET SETTER spécifique à Chien # ============================================ # GETTER pour l'attribut race def get_race(self): """ Getter pour l'attribut race. Retourne la valeur actuelle de la race. """ return self._race # SETTER pour l'attribut race def set_race(self, nouvelle_race: str): """ Setter pour l'attribut race. Modifie la valeur de la race avec la nouvelle valeur. """ self._race = nouvelle_race # ============================================ # Surcharge de la méthode afficher_infos (optionnel) # ============================================ def afficher_infos(self): """ Surcharge de la méthode afficher_infos de la classe parent. Appelle d'abord la méthode de la classe parent, puis ajoute l'affichage de la race spécifique au chien. """ # Appel de la méthode de la classe parent super().afficher_infos() # Ajout de l'affichage spécifique au chien print(f"Race: {self._race}") # ============================================ # PARTIE 3 : TEST DU PROGRAMME # ============================================ """ Bloc principal de test. Ce code ne s'exécute que si le fichier est lancé directement (et non importé comme module). """ print("=" * 50) print("TEST COMPLET DE LA HIÉRARCHIE DE CLASSES") print("=" * 50) # ----------------------------------------------------------------- # Étape 1 : Création d'un objet Chien # ----------------------------------------------------------------- print("\n1. CRÉATION D'UN CHIEN") print("-" * 30) # Instanciation d'un objet Chien avec des valeurs initiales mon_chien = Chien( nom="Rex", # Valeur pour l'attribut hérité 'nom' age=3, # Valeur pour l'attribut hérité 'age' espece="Canidé", # Valeur pour l'attribut hérité 'espece' race="Berger Allemand" # Valeur pour l'attribut spécifique 'race' ) print("Chien créé avec succès!") # ----------------------------------------------------------------- # Étape 2 : Affichage initial des informations # ----------------------------------------------------------------- print("\n2. AFFICHAGE DES INFORMATIONS INITIALES") print("-" * 40) print("\nA. Méthode afficher_infos() (héritée et surchargée):") print("-" * 30) mon_chien.afficher_infos() # Utilise la version surchargée de la méthode print("\nB. Méthode afficher_race() (spécifique à Chien):") print("-" * 30) mon_chien.afficher_race() # Utilise la méthode spécifique à Chien print("\nC. Utilisation des getters pour vérifier les valeurs:") print("-" * 30) # Test des getters hérités de Animal print(f"Nom (via getter): {mon_chien.get_nom()}") print(f"Âge (via getter): {mon_chien.get_age()} ans") print(f"Espèce (via getter): {mon_chien.get_espece()}") # Test du getter spécifique à Chien print(f"Race (via getter): {mon_chien.get_race()}") # ----------------------------------------------------------------- # Étape 3 : Modification des attributs avec les setters # ----------------------------------------------------------------- print("\n3. MODIFICATION DES ATTRIBUTS") print("-" * 30) print("\nA. Modification de l'âge (de 3 à 4 ans):") print("-" * 30) print(f"Âge avant modification: {mon_chien.get_age()} ans") mon_chien.set_age(4) # Utilisation du setter pour modifier l'âge print(f"Âge après modification: {mon_chien.get_age()} ans") print("\nB. Modification de la race:") print("-" * 30) print(f"Race avant modification: {mon_chien.get_race()}") mon_chien.set_race("Berger Australien") # Utilisation du setter pour modifier la race print(f"Race après modification: {mon_chien.get_race()}") print("\nC. Modification du nom (juste pour l'exemple):") print("-" * 30) print(f"Nom avant modification: {mon_chien.get_nom()}") mon_chien.set_nom("Max") print(f"Nom après modification: {mon_chien.get_nom()}") # ----------------------------------------------------------------- # Étape 4 : Affichage final pour vérification # ----------------------------------------------------------------- print("\n4. VÉRIFICATION FINALE") print("-" * 30) print("\nA. Toutes les informations mises à jour:") print("-" * 30) mon_chien.afficher_infos() print("\nB. Récupération individuelle via getters:") print("-" * 30) print(f"Nom final: {mon_chien.get_nom()}") print(f"Âge final: {mon_chien.get_age()} ans") print(f"Espèce finale: {mon_chien.get_espece()}") print(f"Race finale: {mon_chien.get_race()}") # ----------------------------------------------------------------- # DÉMONSTRATION SUPPLÉMENTAIRE (pour comprendre l'héritage) # ----------------------------------------------------------------- print("\n" + "=" * 50) print("DÉMONSTRATION SUPPLÉMENTAIRE") print("=" * 50) print("\n1. Vérification de l'héritage:") print("-" * 30) print(f"mon_chien est-il une instance de Chien? {isinstance(mon_chien, Chien)}") print(f"mon_chien est-il une instance de Animal? {isinstance(mon_chien, Animal)}") print(f"Chien est-il une sous-classe de Animal? {issubclass(Chien, Animal)}") print("\n2. Création d'un Animal simple (sans héritage):") print("-" * 30) mon_animal = Animal("Félix", 2, "Chat") print("Animal créé:") mon_animal.afficher_infos() # Note: mon_animal n'a pas la méthode afficher_race() car c'est un Animal, pas un Chien print("\n3. Différence entre Animal et Chien:") print("-" * 30) print("L'objet 'mon_animal' (Animal) peut appeler afficher_infos(): OUI") print("L'objet 'mon_animal' peut appeler afficher_race(): NON (erreur si on essaye)") print("L'objet 'mon_chien' (Chien) peut appeler afficher_infos(): OUI (héritée)") print("L'objet 'mon_chien' peut appeler afficher_race(): OUI (spécifique)") print("\n" + "=" * 50) print("FIN DU PROGRAMME - TOUS LES TESTS SONT RÉUSSIS!") print("=" * 50) |
Younes Derfoufi CRMEF OUJDA



