POO Avancée

Introduction à la Programmation Orientée Objet

La Programmation Orientée Objet (POO) est un paradigme puissant qui simplifie la conception, le développement et la maintenance des projets complexes. Elle repose sur l’utilisation de classes et d’objets pour modéliser des entités du monde réel ou abstrait.

Dans ce cours, nous approfondirons les concepts de base de la POO (classes, objets, encapsulation, héritage, polymorphisme) et explorerons des notions avancées comme les classes abstraites, les interfaces et les design patterns simples.


Concepts Avancés de la POO

1. Classe et Objet : Rappel

  • Une classe définit une structure générique (attributs et méthodes).
  • Un objet est une instance concrète de cette classe.

2. Encapsulation et Modificateurs d’Accès

  • Privé (__) : Les attributs ou méthodes ne sont accessibles que depuis l’intérieur de la classe.
  • Protégé (_) : Accès autorisé depuis la classe ou ses sous-classes.
  • Public : Accès autorisé depuis n’importe où.

Exemple :

class Produit:
    def __init__(self, nom, prix):
        self.__nom = nom
        self.__prix = prix

    def get_nom(self):
        return self.__nom

    def set_prix(self, nouveau_prix):
        if nouveau_prix > 0:
            self.__prix = nouveau_prix
        else:
            print("Le prix doit être positif.")

    def afficher_produit(self):
        print(f"Produit: {self.__nom}, Prix: {self.__prix} €")

3. Héritage

  • Permet de créer de nouvelles classes basées sur des classes existantes.
  • Une classe fille hérite des attributs et méthodes de sa classe parente.
  • Possibilité de redéfinir ou d'ajouter des fonctionnalités.

Exemple :

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

    def demarrer(self):
        print(f"{self.marque} {self.modele} démarre.")

class Voiture(Vehicule):
    def __init__(self, marque, modele, nb_portes):
        super().__init__(marque, modele)
        self.nb_portes = nb_portes

    def afficher_info(self):
        print(f"Voiture: {self.marque} {self.modele}, {self.nb_portes} portes.")

ma_voiture = Voiture("Toyota", "Corolla", 5)
ma_voiture.demarrer()
ma_voiture.afficher_info()

4. Polymorphisme et Redéfinition

  • Permet à une même méthode d'avoir des comportements différents selon la classe.

Exemple :

class Animal:
    def parler(self):
        pass

class Chien(Animal):
    def parler(self):
        return "Woof"

class Chat(Animal):
    def parler(self):
        return "Meow"

animaux = [Chien(), Chat()]
for animal in animaux:
    print(animal.parler())

5. Abstraction

  • Les classes abstraites servent de modèles pour d'autres classes. Elles ne peuvent pas être instanciées directement.

Exemple :

from abc import ABC, abstractmethod

class Forme(ABC):
    @abstractmethod
    def aire(self):
        pass

class Rectangle(Forme):
    def __init__(self, largeur, hauteur):
        self.largeur = largeur
        self.hauteur = hauteur

    def aire(self):
        return self.largeur * self.hauteur

rect = Rectangle(5, 10)
print(rect.aire())

Design Patterns Simples

1. Singleton

Assure qu'une classe n'a qu'une seule instance.

class Singleton:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance

obj1 = Singleton()
obj2 = Singleton()
print(obj1 is obj2)  # True

2. Factory Method

Simplifie la création d'objets en déléguant cette responsabilité à une méthode spécialisée.


Exercice: Gestion d’une Entreprise

  1. Créer une classe Employe avec des attributs nom, prenom, et salaire.
  2. Ajouter une classe Manager qui hérite de Employe et inclut une liste de subordonnés.
  3. Implémenter des méthodes pour :
    • Ajouter des subordonnés au manager.
    • Calculer le coût total d'une équipe.
  4. Bonus : Ajouter une classe abstraite Personne comme base pour Employe et Manager.

Conclusion

La POO est essentielle pour gérer la complexité des grands projets en offrant une structure claire et modulaire. Les concepts avancés comme l’héritage, le polymorphisme et les design patterns sont des outils puissants pour écrire du code robuste, réutilisable et évolutif.

Exercice pour les élèves :
- Implémentez une classe abstraite Animal avec une méthode se_deplacer().
- Créez des classes Oiseau et Poisson qui redéfinissent cette méthode.
- Simulez une collection d'animaux et appelez leurs méthodes respectives.