Aller au contenu

L’évolution d’un objet dans le temps

Jusqu’ici, on a vu que :

  • un objet a un état (ses attributs)
  • des méthodes peuvent modifier cet état

Mais il y a un point absolument crucial en programmation orientée objet, et souvent mal compris au début :

un objet évolue dans le temps.

Et si on ne comprend pas bien comment ça marche, on peut très vite écrire du code… surprenant.


Un objet n’est pas figé

Regardez ce code :

class Personnage:
    def __init__(self, nom, vie):
        self.nom = nom
        self.vie = vie

    def prendre_degats(self, degats):
        self.vie -= degats

Puis :

p = Personnage("Alice", 100)
p.prendre_degats(30)
p.prendre_degats(20)

print(p.vie)

Ce programme affiche :

50

Pourquoi ? Parce que :

  • l’objet p est le même
  • son état est modifié à chaque appel de méthode
  • les effets s’additionnent dans le temps

L’objet garde en mémoire ce qui lui est arrivé.


Variables et objets : attention à la confusion

Considérez maintenant ce code :

p1 = Personnage("Alice", 100)
p2 = p1

p2.prendre_degats(40)

À ce stade, que valent p1.vie et p2.vie ?

La réponse est :

  • p1.vie == 60
  • p2.vie == 60

Pourquoi ? Parce que p1 et p2 ne sont pas deux objets différents.

Ils pointent vers le même objet.


Une variable ne contient pas l’objet

C’est un point fondamental.

Quand on écrit :

p2 = p1

On ne copie pas l’objet. On copie la référence vers l’objet.

Il n’y a qu’un seul objet en mémoire, et deux variables qui y font référence.

C’est pour ça que :

  • modifier l’objet via p1
  • ou via p2

revient exactement au même.


Deux objets, deux états indépendants

Pour avoir deux objets indépendants, il faut créer deux objets :

p1 = Personnage("Alice", 100)
p2 = Personnage("Alice", 100)

p1.prendre_degats(40)

Ici :

  • p1.vie vaut 60
  • p2.vie vaut toujours 100

Même classe, même valeurs initiales, mais deux objets différents, donc deux états indépendants.


Pourquoi c’est important

Ce comportement est la source :

  • de beaucoup de bugs chez les débutants
  • mais aussi de la puissance de la POO

Comprendre que :

  • les objets vivent dans le temps
  • les variables ne sont que des “étiquettes”
  • plusieurs variables peuvent désigner le même objet

est absolument essentiel pour écrire du code fiable.


Quizz

class Sac:
    def __init__(self, poids):
        self.poids = poids

sac1 = Sac(10)
sac2 = sac1
sac2.poids += 5

print(sac1.poids)
Qu’affiche ce programme ?
- 10
- *15
- Une erreur
> `sac1` et `sac2` pointent vers le même objet. Modifier l’un modifie l’autre.

Exercice pratique

On reprend encore notre bon vieux exemple de jeu.

Créez une classe Personnage avec :

  • un nom
  • des points de vie
  • une méthode pour prendre des dégâts

Créez un personnage, puis :

  • stockez-le dans deux variables différentes
  • modifiez son état via l’une des variables
  • observez ce qui se passe avec l’autre

Puis créez deux personnages distincts avec les mêmes valeurs initiales, et vérifiez qu’ils évoluent indépendamment.

Le but de cet exercice est de bien comprendre la différence entre copier une référence et créer un nouvel objet.


En résumé

Un objet :

  • a un état
  • garde cet état dans le temps
  • peut être référencé par plusieurs variables

Une variable :

  • ne contient pas l’objet
  • elle pointe vers lui

Comprendre ça, c’est éviter une énorme quantité de bugs.

Dans la page suivante, on va enfin mettre tout ça en pratique avec un premier vrai projet orienté objet.