Exercice 01 : Duck Typing avec des Formes Géométriques
Objectif
Cet exercice a pour but de vous faire mettre en pratique le concept de Duck Typing en créant plusieurs classes de formes géométriques qui, bien que n'ayant aucun lien d'héritage, peuvent toutes être utilisées par une même fonction grâce à leur interface commune.
Contexte
Imaginez que vous travaillez sur un programme de dessin. Vous avez besoin de calculer l'aire de différentes formes (carrés, cercles, etc.). Au lieu de forcer toutes vos formes à hériter d'une classe Forme de base, vous allez utiliser le Duck Typing.
Vous allez définir plusieurs classes de formes, chacune avec sa propre méthode calculer_aire(). Ensuite, vous écrirez une fonction qui peut prendre n'importe laquelle de ces formes et afficher son aire.
Énoncé
-
Créez un nouveau fichier Python nommé
formes.py. -
Définissez la classe
Carre.- Le constructeur
__init__doit accepter un argumentcote. - Définissez une méthode
calculer_aire()qui retourne l'aire du carré (cote * cote).
- Le constructeur
-
Définissez la classe
Cercle.- Le constructeur
__init__doit accepter un argumentrayon. - Définissez une méthode
calculer_aire()qui retourne l'aire du cercle (pi * rayon²). Vous pouvez utilisermath.pipour la valeur de pi.
- Le constructeur
-
Définissez la classe
Rectangle.- Le constructeur
__init__doit accepter deux arguments,longueuretlargeur. - Définissez une méthode
calculer_aire()qui retourne l'aire du rectangle (longueur * largeur).
- Le constructeur
-
Définissez une classe qui n'est PAS une forme.
- Créez une classe
Bateauavec un constructeur qui prend unnom. - Cette classe ne doit pas avoir de méthode
calculer_aire().
- Créez une classe
-
Créez une fonction
afficher_aire(forme).- Cette fonction doit prendre un objet
formeen argument. - Elle doit essayer d'appeler la méthode
calculer_aire()de l'objet. - Pour gérer les objets qui n'ont pas cette méthode (comme
Bateau), utilisez un bloctry...except AttributeErrorou la fonctionhasattr(). - Si l'objet a la méthode, la fonction doit afficher un message comme
f"L'aire de la forme est : {aire}". - Si l'objet n'a pas la méthode, elle doit afficher un message comme
f"L'objet {type(forme).__name__} n'a pas de méthode pour calculer l'aire.".
- Cette fonction doit prendre un objet
-
Testez votre code.
- Créez une liste contenant des instances de
Carre,Cercle,Rectangle, etBateau. - Itérez sur cette liste et appelez
afficher_aire()pour chaque objet.
- Créez une liste contenant des instances de
Résultat Attendu
Votre script doit démontrer que la fonction afficher_aire peut interagir avec n'importe quelle forme qui "cancane" comme une forme (c'est-à-dire, qui a une méthode calculer_aire), et qu'elle gère gracieusement les objets qui ne le font pas.
L'aire de la forme est : 25
L'aire de la forme est : 78.53981633974483
L'aire de la forme est : 24
L'objet Bateau n'a pas de méthode pour calculer l'aire.
Cliquez ici pour voir un exemple de code de solution
# formes.py
import math
# --- Définition des classes de formes ---
class Carre:
def __init__(self, cote: float):
self.cote = cote
def calculer_aire(self) -> float:
"""Calcule l'aire du carré."""
return self.cote * self.cote
class Cercle:
def __init__(self, rayon: float):
self.rayon = rayon
def calculer_aire(self) -> float:
"""Calcule l'aire du cercle."""
return math.pi * (self.rayon ** 2)
class Rectangle:
def __init__(self, longueur: float, largeur: float):
self.longueur = longueur
self.largeur = largeur
def calculer_aire(self) -> float:
"""Calcule l'aire du rectangle."""
return self.longueur * self.largeur
# --- Classe qui ne respecte pas l'interface ---
class Bateau:
def __init__(self, nom: str):
self.nom = nom
# --- Fonction polymorphique utilisant le Duck Typing ---
def afficher_aire(forme):
"""
Affiche l'aire d'un objet s'il possède une méthode calculer_aire().
"""
# On vérifie si l'objet a le comportement attendu (la méthode)
if hasattr(forme, 'calculer_aire') and callable(forme.calculer_aire):
aire = forme.calculer_aire()
print(f"L'aire de la forme ({type(forme).__name__}) est : {aire}")
else:
print(f"L'objet {type(forme).__name__} n'a pas de méthode pour calculer l'aire.")
# --- Tests ---
if __name__ == "__main__":
# Création d'objets de types différents.
# Ils ne partagent aucun lien d'héritage.
mon_carre = Carre(cote=5)
mon_cercle = Cercle(rayon=5)
mon_rectangle = Rectangle(longueur=6, largeur=4)
mon_bateau = Bateau(nom="Titanic")
# Création d'une liste d'objets hétérogènes
objets = [mon_carre, mon_cercle, mon_rectangle, mon_bateau]
# La fonction afficher_aire fonctionne avec tous les objets
# qui ont la bonne "interface" (la méthode calculer_aire).
for obj in objets:
afficher_aire(obj)