■
PROGRAMMATION
ORIENTÉE OBJET
Guide Complet — Du Procédural à l'Objet
Langage Python · Niveau Débutant → Avancé
Rédigé par votre Professeur · Université
Support de cours — 2025/2026
Guide Complet — Programmation Orientée Objet en Python Page 1
Table des Matières
Chapitre 1 — Avant de Commencer : La Programmation Procédurale
• 1.1 Rappel : variables, fonctions, boucles
• 1.2 Les limites du procédural
• 1.3 Pourquoi a-t-on inventé la POO ?
Chapitre 2 — Les Concepts Fondamentaux de la POO
• 2.1 Classe et Objet
• 2.2 Attributs et Méthodes
• 2.3 Le constructeur __init__
• 2.4 Le mot-clé self
Chapitre 3 — Encapsulation
• 3.1 Définition
• 3.2 Attributs publics, protégés et privés
• 3.3 Getters et Setters
Chapitre 4 — Héritage
• 4.1 Définition et syntaxe
• 4.2 Surcharge de méthode
• 4.3 La fonction super()
• 4.4 Héritage multiple
Chapitre 5 — Polymorphisme
• 5.1 Définition
• 5.2 Polymorphisme par héritage
• 5.3 Duck Typing en Python
Chapitre 6 — Abstraction
• 6.1 Définition
• 6.2 Classes abstraites avec ABC
• 6.3 Interfaces en Python
Chapitre 7 — Méthodes et Attributs Spéciaux
• 7.1 Méthodes magiques (Dunder Methods)
• 7.2 Méthodes statiques et de classe
• 7.3 Propriétés (@property)
Chapitre 8 — Concevoir une Application en POO
• 8.1 Analyse du problème
• 8.2 Identifier les classes
• 8.3 Diagramme de classes (UML simplifié)
• 8.4 Projet guidé : Système de Bibliothèque
Chapitre 9 — Bonnes Pratiques et Erreurs Courantes
Guide Complet — Programmation Orientée Objet en Python Page 2
• 9.1 Principes SOLID (introduction)
• 9.2 Erreurs fréquentes des débutants
• 9.3 Conseils du professeur
Chapitre 10 — Exercices Pratiques et Corrigés
• 10.1 Exercice 1 : Classe Voiture
• 10.2 Exercice 2 : Héritage Animal
• 10.3 Exercice 3 : Système bancaire
Guide Complet — Programmation Orientée Objet en Python Page 3
Chapitre 1 — Avant de Commencer : La
Programmation Procédurale
1.1 Rappel : variables, fonctions, boucles
Avant d'aborder la POO, rappelons ce que vous maîtrisez déjà. En programmation procédurale, votre
code s'exécute ligne par ligne, de haut en bas. Vous utilisez des variables pour stocker des données, des
fonctions pour regrouper des instructions réutilisables, et des boucles pour répéter des opérations.
Exemple typique en procédural :
# Programme procédural : gérer un étudiant
nom = 'Alice'
age = 20
notes = [15, 12, 18, 10]
def calculer_moyenne(liste_notes):
total = 0
for note in liste_notes:
total = total + note
moyenne = total / len(liste_notes)
return moyenne
def afficher_etudiant(nom, age, notes):
moy = calculer_moyenne(notes)
print('Nom :', nom)
print('Age :', age)
print('Moyenne :', moy)
afficher_etudiant(nom, age, notes)
1.2 Les limites du procédural
Ce style fonctionne très bien pour des petits programmes. Mais imaginez que vous devez gérer 100
étudiants, chacun avec un nom, un âge, des notes, un parcours, une adresse... Le code devient vite un
cauchemar :
• Les données (variables) et les fonctions sont séparées — on perd le lien entre elles.
• Si on ajoute un nouveau champ (ex. adresse), il faut modifier TOUTES les fonctions.
• Le code devient difficile à lire, à maintenir et à partager en équipe.
• On risque de mélanger les données de différents étudiants par erreur.
• Il est impossible de 'modéliser' des entités réelles complexes proprement.
1.3 Pourquoi a-t-on inventé la POO ?
La Programmation Orientée Objet est née pour répondre à ces problèmes. L'idée centrale est simple et
brillante : regrouper ensemble les données et les fonctions qui les manipulent dans une entité
appelée objet. De cette façon, votre code ressemble davantage à la réalité. Un étudiant RÉEL possède un
nom, un âge, des notes et sait calculer sa moyenne. En POO, vous créez un 'moule' qui reproduit
Guide Complet — Programmation Orientée Objet en Python Page 4
exactement cela.
Analogie du Professeur
Imaginez un formulaire vierge d'inscription à l'université. Ce formulaire est le 'moule' (= la Classe).
Chaque étudiant qui remplit ce formulaire crée sa propre fiche avec ses données personnelles (= un
Objet). Tous les étudiants ont la même structure, mais des valeurs différentes.
Guide Complet — Programmation Orientée Objet en Python Page 5
Chapitre 2 — Les Concepts Fondamentaux
de la POO
2.1 Classe et Objet
Une classe est un plan, un modèle, un moule. Elle définit la structure et le comportement d'un type
d'entité. Un objet (ou instance) est une réalisation concrète de ce plan. On peut créer autant d'objets
qu'on veut à partir d'une même classe.
Notre premier exemple complet :
# Définition de la CLASSE (le moule)
class Etudiant:
pass # classe vide pour l'instant
# Création d'OBJETS (instances de la classe)
etudiant1 = Etudiant()
etudiant2 = Etudiant()
# Ces deux objets sont distincts
print(type(etudiant1)) #
print(etudiant1 == etudiant2) # False
2.2 Attributs et Méthodes
Une classe contient deux types d'éléments :
• Attributs : les données, les caractéristiques de l'objet (nom, âge, notes...)
• Méthodes : les fonctions associées à l'objet (calculer_moyenne, se_presenter...)
2.3 Le Constructeur __init__
Le constructeur est une méthode spéciale appelée automatiquement à la création d'un objet. Elle s'appelle
toujours __init__ (deux underscores de chaque côté). C'est ici qu'on initialise les attributs de l'objet.
class Etudiant:
# Le constructeur : appelé automatiquement à la création
def __init__(self, nom, age):
[Link] = nom # attribut nom
[Link] = age # attribut age
[Link] = [] # liste vide au départ
# Une méthode : ajouter une note
def ajouter_note(self, note):
[Link](note)
# Une méthode : calculer la moyenne
def calculer_moyenne(self):
if len([Link]) == 0:
return 0
total = sum([Link])
return total / len([Link])
# Une méthode : afficher les infos
Guide Complet — Programmation Orientée Objet en Python Page 6
def se_presenter(self):
moy = self.calculer_moyenne()
print('Je suis', [Link], ', age :', [Link])
print('Ma moyenne est :', moy)
# Création de deux étudiants
alice = Etudiant('Alice', 20)
bob = Etudiant('Bob', 22)
alice.ajouter_note(15)
alice.ajouter_note(18)
alice.ajouter_note(12)
bob.ajouter_note(10)
bob.ajouter_note(14)
alice.se_presenter()
bob.se_presenter()
2.4 Le mot-clé self
Le paramètre self est la référence à l'objet lui-même. Chaque méthode doit l'avoir en premier paramètre.
Quand vous écrivez alice.se_presenter(), Python traduit cela en Etudiant.se_presenter(alice). Ainsi,
dans la méthode, self représente alice spécifiquement. C'est grâce à self que chaque objet connaît SES
propres données.
Règle d'or
Toute méthode d'une classe commence par self comme premier paramètre. Toute donnée
appartenant à l'objet s'écrit self.nom_attribut. Vous ne passez PAS self lors de l'appel — Python le
fait automatiquement.
Guide Complet — Programmation Orientée Objet en Python Page 7
Chapitre 3 — Encapsulation
3.1 Définition
L'encapsulation est le principe qui consiste à cacher les données internes d'un objet et à n'exposer que
ce qui est nécessaire. C'est comme une capsule médicale : vous avalez le médicament sans vous
préoccuper de sa composition chimique interne. En programmation, cela protège les données de
modifications accidentelles.
3.2 Attributs publics, protégés et privés
Convention Syntaxe Signification
Public [Link] Accessible de partout (par défaut)
Protégé self._nom Déconseillé d'accéder hors de la classe (convention)
Privé self.__nom Vraiment caché, Python renomme l'attribut en interne
3.3 Getters et Setters
Pour accéder ou modifier des attributs privés de manière contrôlée, on utilise des méthodes getter
(lecture) et setter (écriture). Cela permet d'ajouter des vérifications avant toute modification.
class CompteBancaire:
def __init__(self, titulaire, solde_initial):
[Link] = titulaire
self.__solde = solde_initial # attribut PRIVÉ
# GETTER : lire le solde
def get_solde(self):
return self.__solde
# SETTER : modifier le solde avec vérification
def deposer(self, montant):
if montant <= 0:
print('Erreur : le montant doit être positif')
return
self.__solde = self.__solde + montant
print('Dépôt de', montant, '€. Nouveau solde :', self.__solde)
def retirer(self, montant):
if montant > self.__solde:
print('Solde insuffisant !')
return
self.__solde = self.__solde - montant
# Utilisation
compte = CompteBancaire('Alice', 1000)
[Link](500) # OK
[Link](200) # OK
print(compte.get_solde()) # 1300
# compte.__solde = -9999 # IMPOSSIBLE (attribut privé)
Guide Complet — Programmation Orientée Objet en Python Page 8
Chapitre 4 — Héritage
4.1 Définition et syntaxe
L'héritage permet à une classe (enfant) de récupérer automatiquement tous les attributs et méthodes
d'une autre classe (parent). C'est le principe de la transmission : un Étudiant est une Personne, donc il
hérite des caractéristiques d'une Personne. On évite ainsi de réécrire du code en commun.
# Classe PARENT (classe mère)
class Personne:
def __init__(self, nom, age):
[Link] = nom
[Link] = age
def se_presenter(self):
print('Je suis', [Link], ', age :', [Link])
def travailler(self):
print([Link], 'est en train de travailler')
# Classe ENFANT (hérite de Personne)
class Etudiant(Personne): # <- Personne entre parenthèses = héritage
def __init__(self, nom, age, numero_etudiant):
super().__init__(nom, age) # appel du constructeur parent
[Link] = numero_etudiant
[Link] = []
def ajouter_note(self, note):
[Link](note)
# Classe ENFANT : Professeur
class Professeur(Personne):
def __init__(self, nom, age, matiere):
super().__init__(nom, age)
[Link] = matiere
def enseigner(self):
print([Link], 'enseigne', [Link])
# Test
etudiant = Etudiant('Alice', 20, 'ETU-001')
prof = Professeur('Dr. Martin', 45, 'Informatique')
etudiant.se_presenter() # méthode héritée de Personne
etudiant.ajouter_note(16) # méthode propre à Etudiant
[Link]() # méthode propre à Professeur
4.2 Surcharge de méthode (Override)
Un enfant peut redéfinir une méthode héritée pour lui donner un comportement différent. C'est ce qu'on
appelle la surcharge (override).
class Animal:
def parler(self):
print('...')
class Chien(Animal):
def parler(self): # surcharge de parler()
Guide Complet — Programmation Orientée Objet en Python Page 9
print('Woof !')
class Chat(Animal):
def parler(self): # surcharge de parler()
print('Miaou !')
# Test
animaux = [Chien(), Chat(), Animal()]
for animal in animaux:
[Link]() # Woof! / Miaou! / ...
4.3 La fonction super()
super() permet d'appeler une méthode de la classe parente depuis la classe enfant. Elle est indispensable
dans __init__ pour ne pas perdre l'initialisation du parent, et dans les méthodes surchargées quand on
veut étendre (et non remplacer) le comportement.
Guide Complet — Programmation Orientée Objet en Python Page 10
Chapitre 5 — Polymorphisme
5.1 Définition
Le polymorphisme (du grec : plusieurs formes) signifie que des objets de types différents peuvent
répondre à la même méthode d'une façon qui leur est propre. En Python, c'est naturel : si des objets ont
une méthode du même nom, vous pouvez les appeler de la même façon sans vous préoccuper de leur
type exact.
5.2 Polymorphisme en action
class Forme:
def aire(self):
return 0
class Rectangle(Forme):
def __init__(self, largeur, hauteur):
[Link] = largeur
[Link] = hauteur
def aire(self):
return [Link] * [Link]
class Cercle(Forme):
def __init__(self, rayon):
[Link] = rayon
def aire(self):
return 3.14159 * [Link] * [Link]
class Triangle(Forme):
def __init__(self, base, hauteur):
[Link] = base
[Link] = hauteur
def aire(self):
return 0.5 * [Link] * [Link]
# POLYMORPHISME : même appel, comportement différent
formes = [Rectangle(5, 3), Cercle(4), Triangle(6, 8)]
for forme in formes:
print('Aire :', [Link]()) # Python choisit la bonne méthode
5.3 Duck Typing en Python
Python va encore plus loin. Il n'est pas nécessaire d'hériter d'une classe commune pour bénéficier du
polymorphisme. Si un objet possède la bonne méthode, Python l'utilisera. C'est le Duck Typing : « Si ça
marche comme un canard et ça cancane comme un canard, c'est un canard. »
# Pas d'héritage commun, mais même interface
class Voiture:
def demarrer(self):
print('Vroum !')
class Avion:
def demarrer(self):
print('Turbines en marche !')
Guide Complet — Programmation Orientée Objet en Python Page 11
class Bateau:
def demarrer(self):
print('Moteur nautique démarré !')
vehicules = [Voiture(), Avion(), Bateau()]
for v in vehicules:
[Link]() # Python appelle la bonne méthode
Guide Complet — Programmation Orientée Objet en Python Page 12
Chapitre 6 — Abstraction
6.1 Définition
L'abstraction consiste à définir un contrat que des classes doivent respecter, sans donner
l'implémentation. Une classe abstraite est une classe que l'on ne peut pas instancier directement. Elle
sert uniquement de modèle pour ses classes filles qui, elles, DOIVENT implémenter les méthodes
abstraites.
6.2 Classes abstraites avec ABC
from abc import ABC, abstractmethod
# Classe abstraite : on ne peut pas faire Forme()
class Forme(ABC):
@abstractmethod
def aire(self):
pass # pas d'implémentation ici
@abstractmethod
def perimetre(self):
pass
# Méthode normale (non abstraite)
def decrire(self):
print('Aire =', [Link](), '| Périmètre =', [Link]())
# Classe concrète : DOIT implémenter aire() et perimetre()
class Rectangle(Forme):
def __init__(self, l, h):
self.l = l
self.h = h
def aire(self):
return self.l * self.h
def perimetre(self):
return 2 * (self.l + self.h)
r = Rectangle(5, 3)
[Link]() # Aire = 15 | Périmètre = 16
# f = Forme() ← INTERDIT : TypeError !
Guide Complet — Programmation Orientée Objet en Python Page 13
Chapitre 7 — Méthodes et Attributs Spéciaux
7.1 Méthodes Magiques (Dunder Methods)
Python réserve des méthodes entourées de double underscores (__) appelées méthodes magiques ou
dunder methods. Elles permettent de personnaliser le comportement de vos objets avec les opérateurs
Python natifs.
Méthode Déclenchée par Usage typique
__init__ MonObjet() Constructeur
__str__ print(obj), str(obj) Représentation lisible
__repr__ repr(obj) Représentation développeur
__len__ len(obj) Taille / longueur
__add__ obj1 + obj2 Addition
__eq__ obj1 == obj2 Comparaison d'égalité
__lt__ obj1 < obj2 Comparaison inférieur
__getitem__ obj[i] Accès par index
__contains__ 'x' in obj Test d'appartenance
Exemple : classe Vecteur avec opérateurs
class Vecteur:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f'Vecteur({self.x}, {self.y})'
def __add__(self, autre):
return Vecteur(self.x + autre.x, self.y + autre.y)
def __eq__(self, autre):
return self.x == autre.x and self.y == autre.y
def __len__(self):
import math
return int([Link](self.x**2 + self.y**2))
v1 = Vecteur(3, 4)
v2 = Vecteur(1, 2)
print(v1) # Vecteur(3, 4)
print(v1 + v2) # Vecteur(4, 6)
print(len(v1)) # 5
7.2 Méthodes statiques et de classe
• @staticmethod : méthode qui n'a pas besoin de l'objet (self) ni de la classe. Utilitaire pur.
• @classmethod : méthode qui reçoit la classe elle-même (cls) plutôt que l'objet. Utilisée pour créer des
Guide Complet — Programmation Orientée Objet en Python Page 14
constructeurs alternatifs.
class Temperature:
def __init__(self, celsius):
[Link] = celsius
# Méthode de classe : constructeur alternatif
@classmethod
def depuis_fahrenheit(cls, fahrenheit):
celsius = (fahrenheit - 32) * 5 / 9
return cls(celsius)
# Méthode statique : utilitaire, pas besoin de self
@staticmethod
def est_valide(celsius):
return celsius >= -273.15
def __str__(self):
return f'{[Link]:.1f} °C'
t1 = Temperature(100) # depuis Celsius
t2 = Temperature.depuis_fahrenheit(212) # depuis Fahrenheit
print(t1) # 100.0 °C
print(t2) # 100.0 °C
print(Temperature.est_valide(-300)) # False
Guide Complet — Programmation Orientée Objet en Python Page 15
Chapitre 8 — Concevoir une Application en
POO
8.1 La Démarche de Conception
Concevoir une application en POO ne s'improvise pas. Votre professeur vous recommande de suivre ces
étapes :
Lisez attentivement le problème. Soulignez les noms (futurs objets) et les
1. Analyser l'énoncé verbes (futures méthodes).
Chaque nom important = une classe candidate. Ex : Livre, Membre,
2. Identifier les classes Bibliothèque, Emprunt.
Pour chaque classe, listez ce qu'elle 'sait' (ses données). Ex : Livre → titre,
3. Définir les attributs auteur, ISBN.
Pour chaque classe, listez ce qu'elle 'peut faire'. Ex : Bibliotheque →
4. Définir les méthodes ajouter_livre(), rechercher().
5. Identifier les
relations Héritage ('est un'), Composition ('possède un'), Association ('connaît un').
6. Coder et tester Implémenter classe par classe. Tester chaque classe indépendamment.
8.2 Projet Guidé : Système de Bibliothèque
Voici un exemple complet et réaliste. Nous allons construire pas à pas un système de gestion de
bibliothèque. L'énoncé : « Une bibliothèque gère des livres et des membres. Un membre peut emprunter
et retourner des livres. Chaque livre a un titre, un auteur et peut être disponible ou non. »
# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
# CLASSE LIVRE
# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
class Livre:
def __init__(self, titre, auteur, isbn):
[Link] = titre
[Link] = auteur
[Link] = isbn
[Link] = True # disponible par défaut
def emprunter(self):
if [Link]:
[Link] = False
return True
return False
def retourner(self):
[Link] = True
Guide Complet — Programmation Orientée Objet en Python Page 16
def __str__(self):
statut = 'Disponible' if [Link] else 'Emprunté'
return f'[{statut}] {[Link]} — {[Link]}'
# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
# CLASSE MEMBRE
# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
class Membre:
def __init__(self, nom, numero_carte):
[Link] = nom
self.numero_carte = numero_carte
[Link] = [] # liste des livres empruntés
def emprunter_livre(self, livre):
if [Link]():
[Link](livre)
print([Link], 'a emprunté :', [Link])
else:
print('Désolé, ce livre n\'est pas disponible')
def retourner_livre(self, livre):
if livre in [Link]:
[Link]()
[Link](livre)
print([Link], 'a retourné :', [Link])
def afficher_emprunts(self):
print('Emprunts de', [Link], ':')
if len([Link]) == 0:
print(' Aucun emprunt en cours')
for livre in [Link]:
print(' -', [Link])
# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
# CLASSE BIBLIOTHEQUE
# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
class Bibliotheque:
def __init__(self, nom):
[Link] = nom
[Link] = []
[Link] = []
def ajouter_livre(self, livre):
[Link](livre)
def inscrire_membre(self, membre):
[Link](membre)
def rechercher_titre(self, titre):
resultats = []
for livre in [Link]:
if [Link]() in [Link]():
[Link](livre)
return resultats
def afficher_catalogue(self):
print('=== Catalogue de', [Link], '===')
for livre in [Link]:
print(' ', livre)
# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
Guide Complet — Programmation Orientée Objet en Python Page 17
# PROGRAMME PRINCIPAL
# ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
biblio = Bibliotheque('Bibliothèque Centrale')
# Ajout de livres
l1 = Livre('Le Petit Prince', 'Saint-Exupéry', '978-0-15-601219-5')
l2 = Livre('Les Misérables', 'Victor Hugo', '978-0-451-52526-4')
l3 = Livre('Python Avancé', 'John Doe', '978-1-23-456789-0')
biblio.ajouter_livre(l1)
biblio.ajouter_livre(l2)
biblio.ajouter_livre(l3)
# Inscription de membres
alice = Membre('Alice', 'M001')
bob = Membre('Bob', 'M002')
biblio.inscrire_membre(alice)
biblio.inscrire_membre(bob)
# Actions
biblio.afficher_catalogue()
alice.emprunter_livre(l1)
alice.emprunter_livre(l3)
bob.emprunter_livre(l1) # déjà emprunté !
alice.afficher_emprunts()
alice.retourner_livre(l1)
bob.emprunter_livre(l1) # maintenant disponible
Guide Complet — Programmation Orientée Objet en Python Page 18
Chapitre 9 — Bonnes Pratiques et Erreurs
Courantes
9.1 Principes SOLID (Introduction)
Les principes SOLID sont les 5 grands principes de la POO professionnelle. Vous n'avez pas à les
maîtriser immédiatement, mais les connaître vous guidera.
Une classe ne fait QU'UNE chose. La classe Livre gère les données d'un
S — Single Responsibility livre, pas les emprunts.
Une classe doit être ouverte à l'extension (héritage) mais fermée à la
O — Open/Closed modification.
Un objet enfant doit pouvoir remplacer un objet parent sans casser le
L — Liskov Substitution programme.
I — Interface Segregation Mieux vaut plusieurs petites interfaces qu'une grosse interface fourre-tout.
D — Dependency Dépendez des abstractions (classes abstraites), pas des implémentations
Inversion concrètes.
9.2 Erreurs Fréquentes des Débutants
■ Oublier self
Écrire def __init__(nom, age) au lieu de def __init__(self, nom, age). Python ne saura pas à quel objet se
référer.
■ Confondre classe et objet
La classe est le plan, l'objet est la maison construite. On instancie un objet, on ne 'remplit' pas une classe.
■ Modifier des attributs directement
Évitez [Link] = None de l'extérieur. Utilisez des méthodes pour contrôler les changements.
■ Héritage trop profond
5 niveaux d'héritage = désastre de lisibilité. Préférez la composition à l'héritage quand c'est possible.
■ Mettre trop de responsabilités
Une classe qui gère les données, l'affichage, la BDD et les emails viole le principe S de SOLID.
■ Ne pas tester classe par classe
Testez chaque classe indépendamment avant de les combiner. Cela vous fera gagner un temps précieux.
9.3 Conseils du Professeur
■ 1. Commencez TOUJOURS par écrire le __init__ et le __str__. Cela force à réfléchir aux données.
Guide Complet — Programmation Orientée Objet en Python Page 19
■ 2. Testez chaque méthode après l'avoir écrite, ne codez pas tout d'un coup.
■ 3. Dessinez vos classes sur papier avant de coder. Un schéma évite 80% des erreurs.
■ 4. Nommez vos classes avec une majuscule (Etudiant), vos objets avec une minuscule (etudiant).
■ 5. Une méthode qui fait plus de 20 lignes devrait probablement être découpée.
■ 6. La POO n'est pas toujours la bonne solution. Pour un petit script de 30 lignes, le procédural suffit.
■ 7. Lisez du code Python de qualité. La bibliothèque standard de Python est un excellent modèle.
Guide Complet — Programmation Orientée Objet en Python Page 20
Chapitre 10 — Exercices Pratiques et
Corrigés
Exercice 1 — Classe Voiture
Créez une classe Voiture avec les attributs : marque, modele, annee, kilometrage. Ajoutez une méthode
rouler(km) qui augmente le kilométrage. Ajoutez une méthode age() qui retourne l'âge de la voiture (2025
- annee). Créez 2 voitures et faites-les rouler.
Corrigé :
class Voiture:
def __init__(self, marque, modele, annee):
[Link] = marque
[Link] = modele
[Link] = annee
[Link] = 0
def rouler(self, km):
if km > 0:
[Link] = [Link] + km
print([Link], 'a roulé', km, 'km. Total :', [Link], 'km')
def age(self):
return 2025 - [Link]
def __str__(self):
return f'{[Link]} {[Link]} ({[Link]}) — {[Link]} km'
v1 = Voiture('Toyota', 'Corolla', 2018)
v2 = Voiture('Renault', 'Clio', 2022)
[Link](150)
[Link](80)
print(v1) # Toyota Corolla (2018) — 230 km
print('Age :', [Link](), 'ans')
Exercice 2 — Héritage : Animaux
Créez une classe Animal avec nom et age. Créez Chien (hérite d'Animal, ajoute race) et Chat (hérite
d'Animal, ajoute couleur). Chaque classe a sa propre méthode parler(). Créez une liste d'animaux mixtes
et faites-les tous parler.
Corrigé :
class Animal:
def __init__(self, nom, age):
[Link] = nom
[Link] = age
def parler(self):
print([Link], 'fait un son...')
def __str__(self):
return f'{[Link]} ({[Link]} ans)'
class Chien(Animal):
def __init__(self, nom, age, race):
Guide Complet — Programmation Orientée Objet en Python Page 21
super().__init__(nom, age)
[Link] = race
def parler(self):
print([Link], 'aboie : Woof!')
class Chat(Animal):
def __init__(self, nom, age, couleur):
super().__init__(nom, age)
[Link] = couleur
def parler(self):
print([Link], 'miaule : Miaou!')
animaux = [Chien('Rex', 3, 'Berger'), Chat('Luna', 2, 'Noir'), Animal('Perroquet', 5)]
for animal in animaux:
[Link]()
Exercice 3 — Système Bancaire
Créez une classe Compte avec titulaire et solde. Ajoutez deposer(montant), retirer(montant) avec
vérification du solde, et virer(montant, autre_compte) qui transfère de l'argent entre deux comptes.
Testez avec deux comptes.
Corrigé :
class Compte:
def __init__(self, titulaire, solde_initial=0):
[Link] = titulaire
self.__solde = solde_initial
def deposer(self, montant):
if montant <= 0:
print('Montant invalide')
return
self.__solde = self.__solde + montant
print(f'Dépôt {montant}€ → Solde {self.__solde}€')
def retirer(self, montant):
if montant > self.__solde:
print('Solde insuffisant')
return False
self.__solde = self.__solde - montant
return True
def virer(self, montant, autre_compte):
if [Link](montant):
autre_compte.deposer(montant)
print(f'Virement {montant}€ : {[Link]} → {autre_compte.titulaire}')
def __str__(self):
return f'Compte {[Link]} : {self.__solde}€'
alice = Compte('Alice', 1000)
bob = Compte('Bob', 500)
[Link](300, bob)
print(alice)
print(bob)
Guide Complet — Programmation Orientée Objet en Python Page 22
Récapitulatif — Les 4 Piliers de la POO
ENCAPSULATIO Regrouper données + méthodes. Cacher l'interne avec des attributs
N privés (__). Contrôler l'accès via des méthodes.
Une classe enfant hérite de la classe parent. Réutilisation du code.
HÉRITAGE Hiérarchie de types. Mot-clé : super().
POLYMORPHISM Même interface, comportements différents selon l'objet réel. Surcharge
E de méthodes. Duck Typing en Python.
Définir un contrat sans l'implémenter. Classes abstraites (ABC). Forcer
ABSTRACTION les sous-classes à implémenter certaines méthodes.
Votre apprentissage ne s'arrête pas ici. La POO est une façon de penser avant d'être une
syntaxe. Plus vous pratiquerez — en écrivant des classes, en analysant des projets existants, en
faisant les exercices — plus elle deviendra naturelle. N'hésitez pas à revenir à ce guide à
chaque fois que vous avez un doute.
Bon courage et bonne pratique ! ■
Guide Complet — Programmation Orientée Objet en Python Page 23