La programmation Objet
Introduction
La programmation objet est une façon de programmer permettant de matérialiser informatiquement des objets de notre univers, par le biais d'attributs et méthodes.
En programmation objet, un attribut correspond à une propriété
définissant un objet. On peut donc avoir plusieurs attributs, si l'objet a plusieurs propriétés qui le caractérisent. Les méthodes sont des ensembles de fonctions à définir permettant d'interagir directement avec notre objet.
Exemple avec une voiture :

Une voiture est caractérisée par diverses propriétés :
- Une couleur
- Une marque
- Un type de carburant
- Un modèle
- Un kilométrage
- ...
Les méthodes vont permettre d'interagir avec ces propriétés. La fonction rouler(km)
pourra par exemple augmenter le kilométrage de la voiture.
La class(e)
En programmation orientée objet, une classe est un modèle (ou plan de construction) qui sert à créer des objets.
La création d'un objet consiste à définir sa classe avec le mot-clé class
, suivi du nom correspondant à l'objet qu'elle doit matérialiser :
class Voiture :
#tout ce qui est indenté ici fera partie intégrante de la class
Constructeur
Le constructeur est une méthode spéciale d’une classe, qui est appelée automatiquement lorsqu’on crée un nouvel objet. Il sert à initialiser l’objet : c’est-à-dire lui donner ses premières valeurs.
En Python, le constructeur porte toujours le nom __init__
(avec deux underscores avant et après).
class Voiture :
def __init__(self):
print("Voiture construite !")
En Python, self
est un mot utilisé à l’intérieur des classes, il représente l’objet lui-même (l’instance en cours).
C’est grâce à self
que chaque objet peut avoir ses propres valeurs.
Quand le constructeur est écrit, on peut créer des instances
de la classe dans le main, en appelant le nom de la classe, et en précisant les paramètres s'il y en a :
class Voiture :
def __init__(self):
print("Voiture construite !")
v1 = Voiture() # Affiche "Voiture construite !"
v2 = Voiture() # Affiche "Voiture construite !"
Attributs
Les attributs sont les données associées à chaque objet, ils décrivent les caractéristiques de l’objet (exemple : la marque ou la couleur d’une voiture).
Chaque objet possède ses propres valeurs pour les attributs définis dans la classe.
Python permet la création de n'importe quel attribut en écrivant : self.nomAttribut = valeurAttribut
.
class Voiture :
def __init__(self, couleur, marqueV):
self.couleur = couleur #On crée l'attribut "couleur" pour chaque objet, et on lui met le paramètre "couleur"
self.marque = marqueV #On crée l'attribut "marque" pour chaque objet, et on lui met le paramètre "marqueV"
v1 = Voiture("Rouge","Peugeot") # On crée une voiture rouge, de marque Peugeot
v2 = Voiture("Noir", "Renault") #On crée une voiture noire, de marque Renault
print(v1.couleur) #Affiche "Rouge"
print(v2.marque) #Affiche "Renault"
Méthodes
Les méthodes sont des fonctions définies à l’intérieur
d’une classe, elles décrivent les actions ou comportements que l’objet peut réaliser. Elles utilisent souvent les attributs de l’objet pour agir, et doivent également avoir le paramètre self
.
Dans le Main, on appelle les méthodes (et les attributs également) d'un objet en spécifiant la variable de l'objet, suivi d'un point. Le point indique que l'on souhaite utiliser un élément stocké dans notre objet, donc méthodes, ou attributs.
class Voiture :
def __init__(self, couleur, marque):
self.couleur = couleur
self.marque = marque
def affichage(self):
print(self.couleur, self.marque)
v1 = Voiture("Rouge","Peugeot")
v2 = Voiture("Noir", "Renault")
v1.affichage() #Affiche "Rouge" et "Peugeot"
v2.affichage() #Affiche "Noir" et "Renault"
Getter/Setter
Une des règles de la Programmation Orientée Objet est de ne pas pouvoir modifier à notre guise les attributs d'un objet, dans le main, ou fonctions. Pour garder le contrôle des valeurs que l'on utilise, et rendre le code plus propre, on utilise ce qui s'appelle des getter et setter.
Getter
Un getter est une méthode d'une classe permettant de retourner la valeur de l'attribut associé à la fonction. En théorie, il faudrait un getter pour chaque attribut d'une classe.
class Voiture :
def __init__(self, couleur, marque):
self.couleur = couleur
self.marque = marque
def getCouleur(self) :
return self.couleur
def getMarque(self) :
return self.marque
v1 = Voiture("Rouge","Peugeot")
v2 = Voiture("Noir", "Renault")
print(v1.getCouleur()) #retourne et affiche "Rouge"
print(v2.getMarque()) #retourne et affiche "Renault
Setter
À contrario du getter, le setter va affecter une nouvelle valeur à l'attribut dont la méthode va dépendre. Ce mode de fonctionnement permet de contrôler les valeurs, et ainsi ne pas saisir n'importe quoi :
class Voiture :
def __init__(self, couleur, marque):
self.couleur = couleur
self.marque = marque
def setCouleur(self, nouvelleCouleur) :
ensembleCouleur = ["Rouge","Noir","Blanc","Gris"]
if nouvelleCouleur in ensembleCouleur :
self.couleur = nouvelleCouleur
else :
print("La couleur n'est pas disponible")
def getCouleur(self) :
return self.couleur
def getMarque(self) :
return self.marque
v1 = Voiture("Rouge","Peugeot")
v1.setCouleur("Blanc")
print(v1.getCouleur()) #retourne et affiche "Blanc"
v1.setCouleur("Bleu") #Affiche "La couleur n'est pas disponible"
print(v1.getCouleur()) #retourne et affiche "Blanc"
Méthodes spéciales (ou dunders)
En Python, certaines méthodes commencent et se terminent par deux underscores (__
), on les appelle des méthodes spéciales (dunders, pour double underscores).
Elles permettent de définir comment nos objets doivent se comporter dans certaines situations.
__str__
La méthode __str__
définit la représentation texte de l’objet quand on fait un print()
.
Sans ça, Python affiche une adresse mémoire peu lisible.
class Voiture :
def __init__(self, couleur, marque):
self.couleur = couleur
self.marque = marque
def __str__(self):
return f"Voiture {self.marque} de couleur {self.couleur}"
v1 = Voiture("Rouge","Peugeot")
print(v1) # Affiche : Voiture Peugeot de couleur Rouge
__len__(self)
: permet d’utiliser la fonction len(objet).__eq__(self, other)
: permet de comparer deux objets avec ==.__add__(self, other)
: définit l’opérateur + entre deux objets.__repr__(self)
: semblable à__str__
, utilisé pour le débogage.
Grâce à ces méthodes, on rend nos classes plus intuitives et proches du comportement des objets natifs de Python.
Exemple de classe : un carré
Un carré est composé d'une longueur x, qui existe 4 fois (avec un angle de 90°). On pourrait avoir une classe carré, qui permet de créer différents carrés, et de calculer leur périmètre, ou leur aire :
class carre :
def __init__(self, x):
self.cote = x
def affichage(self):
print("côté de longueur ", self.cote)
def aire(self):
return self.cote * self.cote
def perimetre(self):
return self.cote * 4
#Programme principal
#carré 1
c1 = carre(3)
print(c1.aire()) #renvoie 3*3 = 9
print(c1.perimetre()) #renvoie 3*4 = 12
#carré 2
c2 = carre(5)
print(c2.aire()) #renvoie 5*5 = 25
print(c2.cote) #affiche 5
Dans cet exemple, on crée 2 objets de type carre
, dont la variable cote de c1 vaut 3, et celle de c2 vaut 5.
Lors des appels aux méthodes aire et perimetre depuis c1, self est remplacé par c1. Ainsi self.cote
devient c1.cote
.