Skip to main content
Niveau : Avancé

Chapitre 23 : Classes et Objets

class, __init__, self

1. Quoi : La Programmation Orientée Objet (POO)

La Programmation Orientée Objet est un paradigme de programmation qui repose sur le concept d'"objets". Un objet est une entité qui regroupe des données (appelées attributs) et des comportements (appelées méthodes).

  • Une Classe est un plan ou un modèle pour créer des objets. Elle définit les attributs et les méthodes que tous les objets de cette classe auront.
  • Un Objet (ou une instance) est une création concrète à partir d'une classe. Vous pouvez créer de multiples objets à partir d'une seule classe, chacun avec ses propres valeurs d'attributs.

Imaginez que la classe Voiture est le plan de construction. Les objets ma_voiture_rouge et la_voiture_de_mon_voisin sont des voitures réelles construites à partir de ce plan.

2. Pourquoi : Modéliser le monde réel

La POO est extrêmement puissante pour organiser des programmes complexes, car elle permet de modéliser des concepts du monde réel.

  • Encapsulation : Regrouper les données et les comportements qui leur sont liés au sein d'un même objet. Cela rend le code plus organisé et plus facile à gérer.
  • Abstraction : Cacher les détails complexes de l'implémentation et n'exposer qu'une interface simple pour interagir avec l'objet.
  • Héritage : Créer de nouvelles classes basées sur des classes existantes pour réutiliser du code et créer des hiérarchies (ex: une classe Chat et une classe Chien peuvent hériter d'une classe Animal).
  • Polymorphisme : Permettre à des objets de différentes classes de répondre au même message (appel de méthode) de manière spécifique à leur type.

3. Comment : Définir une Classe en Python

A. Syntaxe de base

On définit une classe avec le mot-clé class, suivi du nom de la classe (par convention, en CamelCase).

class Dog:
# Le code de la classe est indenté
pass # 'pass' est un placeholder pour indiquer un bloc vide

B. Le Constructeur : __init__()

La méthode __init__() est une méthode spéciale appelée "constructeur". Elle est exécutée automatiquement chaque fois qu'un nouvel objet de la classe est créé. C'est l'endroit idéal pour initialiser les attributs de l'objet.

  • Le premier paramètre de chaque méthode d'instance est toujours self. self représente l'objet lui-même. C'est à travers self que vous pouvez accéder aux attributs et méthodes de l'objet.
class Dog:
# Le constructeur
def __init__(self, name, age):
# On crée les attributs de l'instance 'self'
self.name = name
self.age = age
print(f"A new dog named {self.name} has been created!")

# Création de deux objets (instances) de la classe Dog
dog1 = Dog("Buddy", 3)
dog2 = Dog("Lucy", 5)

# Chaque objet a ses propres attributs
print(f"{dog1.name} is {dog1.age} years old.") # Buddy is 3 years old.
print(f"{dog2.name} is {dog2.age} years old.") # Lucy is 5 years old.

C. Les Méthodes d'Instance

Les méthodes sont des fonctions définies à l'intérieur d'une classe. Elles représentent les comportements de l'objet. Elles prennent toujours self comme premier argument pour pouvoir accéder aux attributs de l'instance.

class Dog:
def __init__(self, name, age):
self.name = name
self.age = age

# Une méthode d'instance
def bark(self):
print(f"{self.name} says: Woof!")

# Une autre méthode d'instance qui utilise les attributs
def get_human_years(self):
return self.age * 7

# Création d'un objet
my_dog = Dog("Rex", 4)

# Appel des méthodes de l'objet
my_dog.bark() # Rex says: Woof!
human_age = my_dog.get_human_years()
print(f"In human years, {my_dog.name} is {human_age} years old.")

D. Attributs de Classe

Un attribut de classe est une variable qui est partagée par toutes les instances de la classe. On le définit directement sous la déclaration de la classe, en dehors de toute méthode.

class Dog:
# Attribut de classe, partagé par tous les chiens
species = "Canis familiaris"

def __init__(self, name):
self.name = name # Attribut d'instance

dog1 = Dog("Buddy")
dog2 = Dog("Lucy")

# On peut y accéder via la classe ou l'instance
print(Dog.species) # Canis familiaris
print(dog1.species) # Canis familiaris
print(dog2.species) # Canis familiaris

4. Exemple complet : un compte bancaire

class BankAccount:
# Le constructeur initialise le compte avec un nom de titulaire et un solde initial
def __init__(self, owner_name, initial_balance=0):
self.owner_name = owner_name
self.balance = initial_balance
print(f"Account for {self.owner_name} created with balance: ${self.balance}")

# Méthode pour déposer de l'argent
def deposit(self, amount):
if amount > 0:
self.balance += amount
print(f"Deposited ${amount}. New balance: ${self.balance}")
else:
print("Deposit amount must be positive.")

# Méthode pour retirer de l'argent
def withdraw(self, amount):
if 0 < amount <= self.balance:
self.balance -= amount
print(f"Withdrew ${amount}. New balance: ${self.balance}")
else:
print("Invalid withdrawal amount or insufficient funds.")

# Méthode pour afficher le solde
def get_balance(self):
print(f"Current balance for {self.owner_name}: ${self.balance}")

# Utilisation de la classe
account1 = BankAccount("Alice", 500)
account1.deposit(100)
account1.withdraw(50)
account1.withdraw(600) # Tentative de retrait invalide
account1.get_balance()

Exercices :

Exercice 23 - Modélisation d'une Voiture

Objectif

Cet exercice a pour but de vous faire créer votre première classe, Car, pour modéliser un objet simple avec ses attributs (données) et ses méthodes (comportements).

Contexte

Vous allez créer une classe Car qui représente une voiture. Une voiture a une marque, un modèle, une année, et un kilométrage. Elle peut également rouler (ce qui augmente son kilométrage) et afficher ses informations.

Énoncé

  1. Créez un nouveau fichier Python nommé car_model.py.

  2. Définissez la classe Car.

    • Par convention, les noms de classe utilisent le CamelCase.
  3. Écrivez le constructeur __init__ :

    • Il doit accepter trois arguments (en plus de self) : make (la marque), model (le modèle), et year (l'année).
    • À l'intérieur du constructeur, initialisez les attributs d'instance suivants :
      • self.make
      • self.model
      • self.year
      • self.odometer_reading : initialisez cet attribut à 0. Il représentera le kilométrage de la voiture.
  4. Créez une méthode get_descriptive_name :

    • Cette méthode ne prend pas d'autres arguments que self.
    • Elle doit retourner une chaîne de caractères formatée décrivant la voiture, par exemple : "2023 Ford Mustang".
  5. Créez une méthode read_odometer :

    • Cette méthode doit afficher le kilométrage de la voiture de manière claire, par exemple : "This car has 0 miles on it.".
  6. Créez une méthode drive :

    • Cette méthode doit accepter un argument miles (le nombre de kilomètres parcourus).
    • Elle doit vérifier que miles est un nombre positif.
    • Si c'est le cas, elle ajoute ce nombre au self.odometer_reading.
    • Sinon, elle affiche un message d'erreur : "You can't drive negative miles!".
  7. Testez votre classe :

    • Créez une instance de votre classe Car.
    • Appelez get_descriptive_name et affichez le résultat.
    • Appelez read_odometer.
    • Appelez la méthode drive avec une valeur positive (ex: 100) et appelez à nouveau read_odometer pour voir le changement.
    • Appelez la méthode drive avec une valeur négative pour tester la gestion de l'erreur.

Résultat Attendu

2023 Ford Mustang
This car has 0 miles on it.
This car has 100 miles on it.
You can't drive negative miles!
Cliquez ici pour voir un exemple de code de solution
# car_model.py

class Car:
"""A simple attempt to represent a car."""

def __init__(self, make, model, year):
"""Initialize attributes to describe a car."""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0

def get_descriptive_name(self):
"""Return a neatly formatted descriptive name."""
long_name = f"{self.year} {self.make} {self.model}"
return long_name.title()

def read_odometer(self):
"""Print a statement showing the car's mileage."""
print(f"This car has {self.odometer_reading} miles on it.")

def drive(self, miles):
"""Increase the odometer reading by the given amount."""
if miles >= 0:
self.odometer_reading += miles
else:
print("You can't drive negative miles!")

# --- Testing the class ---

# Create an instance of the Car class
my_new_car = Car('ford', 'mustang', 2023)

# Print the descriptive name
print(my_new_car.get_descriptive_name())

# Read the initial odometer reading
my_new_car.read_odometer()

# Drive the car
my_new_car.drive(100)
my_new_car.read_odometer()

# Attempt to drive negative miles
my_new_car.drive(-50)