Exercices Pratiques sur la Programmation Orientée Objet en Python

Définitoin d'une Classe Simple

L'objectif est de créer une classe de base pour représenter un étudiant, en gérant ses informations personnelles et académiques avec des validations de données élémentaires.

class Apprenant:
    def __init__(self, nom, age, note_initiale=0):
        self.nom = nom
        self.age = age
        self.resultat = note_initiale

    def obtenir_details(self):
        return f"Étudiant : {self.nom} | Âge : {self.age} ans | Note actuelle : {self.resultat}/100"

    def mettre_a_jour_resultat(self, nouvelle_note):
        # Validation du type et de la plage de valeurs
        if isinstance(nouvelle_note, (int, float)) and 0 <= nouvelle_note <= 100:
            self.resultat = nouvelle_note
            print(f"Mise à jour réussie pour {self.nom}.")
        else:
            print("Erreur : La note doit être un nombre compris entre 0 et 100.")

if __name__ == "__main__":
    eleve = Apprenant("Alice", 21)
    print(eleve.obtenir_details())
    
    eleve.mettre_a_jour_resultat(92)
    print(eleve.obtenir_details())

Maîtriser l'Encapsulation

L'encapsulation permet de protéger les données sensibles d'un objet. Ici, nous utilisons un attribut privé pour le solde d'un compte bancaire, accessible uniquement via des méthodes sécurisées.

class CompteBancaire:
    def __init__(self, depot_initial=0):
        # Attribut privé pour empêcher l'accès direct externe
        self.__solde = depot_initial

    def deposer(self, montant):
        if montant > 0:
            self.__solde += montant
            print(f"Dépôt de {montant} effectué.")
        else:
            print("Le montant du dépôt doit être positif.")

    def retirer(self, montant):
        if 0 < montant <= self.__solde:
            self.__solde -= montant
            print(f"Retrait de {montant} confirmé.")
        else:
            print("Fonds insuffisants ou montant invalide.")

    def consulter_solde(self):
        return f"Solde actuel : {self.__solde} €"

if __name__ == "__main__":
    mon_compte = CompteBancaire(500)
    mon_compte.deposer(200)
    mon_compte.retirer(150)
    print(mon_compte.consulter_solde())

Héritage et Spécialisation

L'héritage permet de créer des hiérarchies d'objets. Nous définissons une classe parente générique et des classes enfants qui étendent ses fonctionnalités.

class Vehicule:
    def __init__(self, marque, couleur):
        self.marque = marque
        self.couleur = couleur

    def deplacer(self):
        return f"Le véhicule {self.marque} de couleur {self.color} circule."

class Automobile(Vehicule):
    def __init__(self, marque, couleur, portes):
        super().__init__(marque, couleur)
        self.portes = portes

    def deplacer(self):
        return f"La voiture {self.marque} ({self.couleur}, {self.portes} portes) roule sur l'autoroute."

class Velo(Vehicule):
    def __init__(self, marque, couleur, assistance_electrique=False):
        super().__init__(marque, couleur)
        self.is_e_bike = assistance_electrique

    def deplacer(self):
        type_velo = "électrique" if self.is_e_bike else "classique"
        return f"Le vélo {type_velo} {self.marque} de couleur {self.couleur} est en mouvement."

if __name__ == "__main__":
    voiture_test = Automobile("Tesla", "Rouge", 5)
    velo_test = Velo("B'Twin", "Noir", True)
    
    print(voiture_test.deplacer())
    print(velo_test.deplacer())

Polymorphisme avec les Formes Géométriques

Le polymorphisme permet de traiter différents objets de la même manière via une interface commune, même si leur implémentation interne diffère.

import math

class Forme:
    def calculer_surface(self):
        pass

class Cercle(Forme):
    def __init__(self, rayon):
        self.rayon = rayon

    def calculer_surface(self):
        return math.pi * (self.rayon ** 2)

class Carre(Forme):
    def __init__(self, cote):
        self.cote = cote

    def calculer_surface(self):
        return self.cote * self.cote

def afficher_aire(objet_forme):
    print(f"La surface calculée est de : {objet_forme.calculer_surface():.2f}")

if __name__ == "__main__":
    c = Cercle(5)
    s = Carre(4)
    
    afficher_aire(c)
    afficher_aire(s)

Interaction entre Objets : Système de Bibliothèque

Cet exemple illustre comment des objets de classes différentes (Livre et Lecteur) interagissent entre eux pour simuler un processus métier réel.

class Livre:
    def __init__(self, titre, auteur):
        self.titre = titre
        self.auteur = auteur
        self.disponible = True

    def etat_actuel(self):
        return "Disponible" if self.disponible else "Emprunté"

class Membre:
    def __init__(self, pseudo):
        self.pseudo = pseudo
        self.emprunts = []

    def emprunter(self, livre):
        if livre.disponible:
            livre.disponible = False
            self.emprunts.append(livre)
            print(f"{self.pseudo} a emprunté '{livre.titre}'.")
        else:
            print(f"Désolé, '{livre.titre}' n'est pas disponible.")

    def rendre(self, livre):
        if livre in self.emprunts:
            livre.disponible = True
            self.emprunts.remove(livre)
            print(f"{self.pseudo} a rendu '{livre.titre}'.")
        else:
            print(f"Erreur : {self.pseudo} ne possède pas ce livre.")

    def lister_livres(self):
        titres = [l.titre for l in self.emprunts]
        return f"Livres de {self.pseudo} : " + (", ".join(titres) if titres else "Aucun")

if __name__ == "__main__":
    l1 = Livre("Le Petit Prince", "Saint-Exupéry")
    l2 = Livre("1984", "George Orwell")
    
    utilisateur = Membre("Jean-Luc")
    
    utilisateur.emprunter(l1)
    utilisateur.emprunter(l2)
    print(utilisateur.lister_livres())
    
    utilisateur.rendre(l1)
    print(f"Statut du livre 1 : {l1.etat_actuel()}")

Étiquettes: Python OOP encapsulation Héritage polymorphisme

Publié le 29 juillet à 05h10