From 50f8dd0afaf3476a97040557ccce8dba7e03f756 Mon Sep 17 00:00:00 2001 From: Florian Mathieu Date: Fri, 2 Oct 2026 10:31:41 +0200 Subject: [PATCH] =?UTF-8?q?POO=20:=20fiche=20de=20r=C3=A9vision?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- POO/FICHE_REVISION.md | 247 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 POO/FICHE_REVISION.md diff --git a/POO/FICHE_REVISION.md b/POO/FICHE_REVISION.md new file mode 100644 index 0000000..8c337e5 --- /dev/null +++ b/POO/FICHE_REVISION.md @@ -0,0 +1,247 @@ +# 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. + +```python +>>> type(3) + +>>> type("salut") + +>>> type([1, 2]) + +``` + +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 : + +```python +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 : + +```python +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** : + +```python +>>> 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 : + +```python +pikachu.subir_degats(30) +``` + +est exactement équivalent à : + +```python +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.** + +```python +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.** + +```python +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 `` : depuis la Première, vous manipulez des objets. + +--- + +## 7. Pour revoir en vidéo + +[Programmation orientée objet - PYTHON - TLE - Spé NSI](https://www.youtube.com/watch?v=yncatRjlEa0&t=50s), 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.