Files
TermNSI/POO/FICHE_REVISION.md
T
2026-10-02 10:31:41 +02:00

10 KiB

Fiche de révision : la programmation orientée objet

Une fiche pour reprendre les bases, et surtout la différence entre une classe et un objet. Les exemples reprennent le TP Pokémon Arena.


1. Vous faites de la POO depuis la Première

Bonne nouvelle : la POO n'est pas un monde nouveau. Vous utilisez des objets depuis l'année dernière sans le savoir.

>>> type(3)
<class 'int'>
>>> type("salut")
<class 'str'>
>>> type([1, 2])
<class 'list'>

Python vous le dit lui-même : 3 est un objet de la classe int, "salut" un objet de la classe str, [1, 2] un objet de la classe list.

Et quand vous écrivez ma_liste.append(3) ou "salut".upper(), vous appelez une méthode sur un objet. Le point entre les deux signifie : « applique cette méthode à cet objet-là ».

En Terminale, la seule nouveauté, c'est que vous allez écrire vos propres classes.


2. Classe ou objet ? La différence en une image

Reprenons l'image du cours : la classe, c'est le plan d'architecte ; l'objet, c'est la maison construite. Avec un seul plan, on peut construire toute une rue de maisons. Elles ont la même forme, mais chacune a sa propre couleur de volets, ses propres habitants, et si on repeint l'une, les autres ne changent pas.

Avec les Pokémon :

  • la classe Pokemon, c'est le formulaire vierge du Pokédex : il prévoit des cases « nom », « type », « PV », mais il ne contient aucun Pokémon ;
  • un objet, c'est un Pokémon précis, avec ses cases remplies : ce Pikachu-là, avec ses 80 PV.
Classe Objet (ou instance)
C'est… un modèle, un plan un exemplaire construit à partir du modèle
Combien ? écrite une seule fois créé autant de fois qu'on veut
Dans le code class Pokemon: pikachu = Pokemon("Pikachu", "Electrik", 80)
Nom commence par une majuscule une variable, en minuscules
Contient des valeurs ? non, elle décrit quelles données existeront oui, ses propres valeurs

Voici une classe très courte :

class Pokemon:
    def __init__(self, nom, type_pokemon, pv):
        self.nom = nom
        self.type_pokemon = type_pokemon
        self.pv = pv

    def subir_degats(self, degats):
        self.pv = self.pv - degats

Ce code ne crée aucun Pokémon. Il explique seulement comment en fabriquer un. Les objets naissent ici :

pikachu = Pokemon("Pikachu", "Electrik", 80)
autre_pikachu = Pokemon("Pikachu", "Electrik", 80)

Deux objets, construits avec le même plan et les mêmes valeurs. Ce sont pourtant deux Pokémon différents :

>>> autre_pikachu.subir_degats(30)
>>> pikachu.pv
80
>>> autre_pikachu.pv
50

Le premier Pikachu n'a rien senti. Chaque objet a ses propres attributs, rangés dans sa propre « boîte ».

!!! tip "À retenir"

**Un objet n'existe que lorsqu'on appelle la classe avec des parenthèses** : `Pokemon(...)`. Chaque appel fabrique un **nouvel** objet. Écrire `class Pokemon:` ne fabrique rien.

3. Le constructeur et self

Que se passe-t-il exactement quand on écrit pikachu = Pokemon("Pikachu", "Electrik", 80) ?

  1. Python fabrique un objet vide de la classe Pokemon.
  2. Il appelle automatiquement la méthode __init__, le constructeur, en lui donnant cet objet vide comme premier paramètre, self.
  3. __init__ remplit l'objet : self.nom = nom signifie « range la valeur nom dans la case nom de cet objet-là ».
  4. L'objet rempli est rangé dans la variable pikachu.

self désigne donc toujours l'objet sur lequel on est en train de travailler. C'est la même chose pour les autres méthodes :

pikachu.subir_degats(30)

est exactement équivalent à :

Pokemon.subir_degats(pikachu, 30)

Python fait cette traduction tout seul : l'objet placé avant le point devient self. C'est pour cela que self apparaît dans la définition de la méthode, mais jamais entre les parenthèses à l'appel.


4. Le vocabulaire

Mot Sens Dans le TP Pokémon
Classe le modèle Pokemon, Dresseur, Combat
Objet ou instance un exemplaire créé à partir de la classe pikachu, salameche, sacha
Instanciation le fait de créer un objet Pokemon("Pikachu", "Electrik", 80)
Attribut une donnée rangée dans l'objet pikachu.pv, pikachu.nom
Méthode une fonction définie dans la classe, qui agit sur un objet pikachu.attaquer(salameche)
Constructeur la méthode __init__, appelée à la création remplit nom, type_pokemon, pv
self l'objet sur lequel la méthode travaille pikachu quand on écrit pikachu.attaquer(...)

5. Les erreurs classiques

Oublier self dans la définition d'une méthode.

def __init__(nom):          # faux
def __init__(self, nom):    # juste

Python répond : TypeError: Pokemon.__init__() takes 1 positional argument but 2 were given. Il a bien transmis deux choses, l'objet et le nom, mais la méthode n'avait prévu de place que pour une.

Écrire nom = nom au lieu de self.nom = nom.

Sans self., la valeur est rangée dans une variable qui disparaît à la fin de __init__, pas dans l'objet. Plus tard, pikachu.nom provoque : AttributeError: 'Pokemon' object has no attribute 'nom'.

Appeler une méthode sur la classe au lieu de l'objet.

Pokemon.subir_degats(10)     # faux : quel Pokémon subit les dégâts ?
pikachu.subir_degats(10)     # juste

C'est exactement la confusion entre classe et objet : la classe est un plan, on ne blesse pas un plan.

Utiliser print au lieu de return dans __repr__.

__repr__ doit renvoyer un texte, pas l'afficher. Avec un print, Python se plaint : TypeError: __str__ returned non-string (type NoneType).


6. Un peu d'histoire

!!! info "1967 : des classes pour simuler des navires"

À Oslo, deux chercheurs norvégiens, **Ole-Johan Dahl** et **Kristen Nygaard**, veulent simuler des systèmes réels : des files d'attente, du trafic, des navires dans un port. Ils créent le langage **Simula 67**, qui invente les **classes** et les **objets** : chaque navire du port devient un objet construit sur le modèle « navire ». C'est exactement l'idée de cette fiche, un plan et des exemplaires. Ils ont reçu en 2001 le **prix Turing**, l'équivalent du prix Nobel de l'informatique.

!!! info "Alan Kay et l'expression « orienté objet »"

Dans les années 1970, au centre de recherche de Xerox à Palo Alto, **Alan Kay** et son équipe créent le langage **Smalltalk**, où absolument tout est un objet. Alan Kay raconte que c'est lui qui a inventé l'expression « programmation orientée objet ». Des années plus tard, devant une salle d'informaticiens, il ajoutera avec malice : « J'ai inventé l'expression orienté objet, et je peux vous dire que je ne pensais pas à C++. »

!!! info "Et Python dans tout ça ?"

Python pousse cette idée aussi loin que Smalltalk : en Python, **tout est objet**. Les nombres, les textes, les listes, et même les fonctions et les classes elles-mêmes. C'est pour cela que `type(3)` répond `<class 'int'>` : depuis la Première, vous manipulez des objets.

7. Pour revoir en vidéo

Programmation orientée objet - PYTHON - TLE - Spé NSI, par David Latouche (2020).

Regardez de 0:50 à 9:51 : les concepts clés, la déclaration d'une classe et le constructeur, l'instanciation d'un objet, les attributs et les méthodes. La suite (encapsulation, héritage, polymorphisme) dépasse le programme de Terminale.


8. À vous

!!! question "Exercice 1 : Classe ou objet ?"

Dans le code ci-dessous, indiquez pour chaque nom s'il désigne une **classe**, un **objet**, un **attribut** ou une **méthode** : `Dresseur`, `sacha`, `equipe`, `ajouter`, `pikachu`.

```python
class Dresseur:
    def __init__(self, nom):
        self.nom = nom
        self.equipe = []

    def ajouter(self, pokemon):
        self.equipe.append(pokemon)

sacha = Dresseur("Sacha")
sacha.ajouter(pikachu)
```

??? success "Correction de l'exercice 1"

- `Dresseur` : une **classe** (mot-clé `class`, majuscule).
- `sacha` : un **objet**, créé par `Dresseur("Sacha")`.
- `equipe` : un **attribut** (`self.equipe`), la liste des Pokémon du dresseur.
- `ajouter` : une **méthode**, définie dans la classe et appelée sur l'objet `sacha`.
- `pikachu` : un **objet**, de la classe `Pokemon`. Ce n'est pas parce qu'il est rangé dans l'équipe de Sacha qu'il devient un `Dresseur`.

!!! question "Exercice 2 : Combien d'objets ?"

Avec la classe `Pokemon` de la partie 2 :

```python
a = Pokemon("Évoli", "Normal", 55)
b = Pokemon("Évoli", "Normal", 55)
c = a
b.subir_degats(10)
c.subir_degats(5)
```

1. Combien d'objets `Pokemon` ont été créés ?
2. Que valent `a.pv`, `b.pv` et `c.pv` ?

??? success "Correction de l'exercice 2"

1. **Deux objets** seulement. Seuls `Pokemon(...)` avec des parenthèses fabriquent un objet, et il y en a deux. `c = a` ne crée rien : c'est un **deuxième nom** pour le même objet que `a`.
2. `a.pv` vaut **50**, `b.pv` vaut **45** et `c.pv` vaut **50**. `b` a subi 10 dégâts. `c` et `a` étant le même Pokémon, les 5 dégâts infligés « à `c` » sont subis par `a`.

!!! question "Exercice 3 : Écrire une classe"

Écrivez une classe `Badge` dont le constructeur reçoit un `nom` et une `ville`, et range ces deux valeurs dans l'objet. Créez ensuite le badge « Roche » de la ville d'Argenta, puis affichez sa ville.

??? success "Correction de l'exercice 3"

```python
class Badge:
    def __init__(self, nom, ville):
        self.nom = nom
        self.ville = ville

badge_roche = Badge("Roche", "Argenta")
print(badge_roche.ville)
```

Points à vérifier : `self` en premier paramètre de `__init__`, `self.nom` et `self.ville` (et pas `nom = nom`), et l'objet créé avec des parenthèses avant d'accéder à son attribut.

Auteur : Florian Mathieu

Licence CC BY-SA

Licence Creative Commons
Ce cours est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 4.0 International.