Commencer avec l'objet
Préambule
L’objectif de ce livre est d’apprendre la logique de programmation afin de pouvoir programmer vos premiers scripts en Python. Tout apprentissage du développement informatique commence par ce que nous avons vu jusqu’à présent : la programmation impérative, ou procédurale si vous préférez.
Ce style de programmation est à la base de toutes les autres, que ce soit la programmation fonctionnelle ou la Programmation Orientée Objet (POO ou Object-Oriented Programming en anglais), les deux grands courants actuels du développement informatique.
À l’heure de l’écriture de ce livre, nous pouvons voir un style de programmation revenir sur le devant de la scène : la programmation fonctionnelle. Il s’agit d’un style utilisé quasiment à la naissance de la machine et commençant à être implémenté dans la plupart des langages. La programmation fonctionnelle moderne en est encore à ses débuts et elle est le plus souvent utilisée pour traiter des masses de données comme en Big Data par exemple, c’est pourquoi nous ne l’introduisons pas dans cet ouvrage.
La programmation orientée objet détient facilement aujourd’hui plus de 80 % des parts du marché du développement informatique. Elle est apparue au début des...
Le naturel de l’objet
1. Introduction
La programmation orientée objet découle de la pensée humaine. C’est une technique de programmation de haut niveau qui permet aux développeurs de modéliser leurs données comme dans la vie réelle.
Par cela, nous voulons dire que ce type de programmation est inspiré des objets de la vraie vie. Prenons un simple objet comme une bouteille d’eau. Chaque bouteille d’eau a ses propres particularités tout en restant au fond une bouteille d’eau. En programmation orientée objet, nous pouvons traduire cet exemple avec une classe BouteilleEau qui décrit les propriétés de chaque bouteille d’eau : sa contenance et si elle est minérale et/ou gazeuse. Ainsi, avec cette classe, nous pouvons créer plusieurs bouteilles d’eau, nos objets, qui auront tous une valeur donnée pour leur contenance et leur type d’eau.
Plus simplement, voyez les classes comme l’évolution des STRUCTURES et les objets comme l’évolution des ENREGISTREMENTS. Les structures, comme les classes, permettent de lier différentes variables dans un même nouveau type de données. Les classes lient en plus les traitements et les variables sur lesquels ils portent. Une structure est instanciée avec un enregistrement et une classe avec un objet.
La programmation orientée objet va beaucoup loin qu’une simple évolution des STRUCTURES, elle permet d’avoir un code mieux organisé, c’est-à-dire organisé de manière plus intuitive pour l’humain, tout en factorisant un maximum de code.
2. L’objet et la classe
La classe nous permet de modéliser nos données dans un algorithme ou dans un programme avec une nouvelle organisation.
Nous regroupons les champs d’une structure en tant qu’ attributs de la classe et les fonctions et procédures qui manipulent ces champs comme méthodes de la classe.
Vous pouvez voir la classe comme un nouveau type de donnée...
Travailler avec les objets
1. Introduction
Les premières sections de ce chapitre ont présenté les principes des classes et des objets. Cette section est dédiée à la manipulation des objets, de leur création jusqu’à leur destruction en mémoire.
Comme le lecteur peut s’en douter, une classe étant une structure de données plus que complexe, un objet sera donc forcément un pointeur.
2. Instanciation et allocation mémoire
Pour instancier un objet, nous utiliserons le même opérateur que pour les pointeurs : NOUVEAU. Cependant, ce qui suit cet opérateur va être différent, cela ne sera pas le nom de la classe, mais le constructeur de la classe.
a. Constructeur
Le constructeur d’une classe est une méthode obligatoire dans la classe. Il permet d’allouer la mémoire de l’objet qui instancie la classe.
Le constructeur a toujours le même nom que la classe et ne retourne rien. Il peut prendre des paramètres ou non, selon nos besoins.
Par convention, le constructeur prend en paramètres les valeurs à affecter aux attributs de l’objet. Dans le cas d’un constructeur sans paramètre, que nous appelons constructeur par défaut, il initialise les attributs à des valeurs par défaut comme son nom l’indique.
Le constructeur se définit par le mot-clé CONSTRUCTEUR en premier dans le bloc des méthodes publiques et ce, en étant la première méthode de ce bloc.
Implémentons donc un constructeur dans notre classe Produit pour illustrer cette méthode spécifique.
CLASSE Produit
ATTRIBUT PUBLIC
DEBUT
quantite : ENTIER
FIN
ATTRIBUT PRIVE
DEBUT
nom : CHAINE
FIN
METHODE PUBLIC
DEBUT
CONSTRUCTEUR Produit(name : CHAINE, combien : ENTIER)
DEBUT
nom <- name
quantite <- combien
FIN
PROCEDURE diminuer_quantite(E : combien : ENTIER)
DEBUT
quantite <- quantite - combien
FIN
FIN
METHODE PRIVEE
DEBUT ...
Pour aller plus loin
1. Polymorphisme
Le polymorphisme est un grand mot pour décrire un comportement tout à fait logique de l’héritage dans la programmation orientée objet. Il amplifie le lien entre une classe mère et ses classes filles, aussi bien au niveau de l’instanciation qu’au niveau de l’implémentation des méthodes.
a. Objet
Grâce au polymorphisme, un objet de type de la classe mère peut appeler le constructeur d’une de ses classes fille. Pour vous en souvenir, vous pouvez utiliser la technique mnémonique suivante : une mère peut être enceinte d’une fille, donc la contenir, mais une fille ne peut pas être enceinte de sa mère.
Ainsi nous pouvons rendre notre classe MaillonDouble adéquate :
Classe Maillon
ATTRIBUT PUBLIC
DEBUT
valeur : type
suivant: Maillon
FIN
METHODE PUBLIC
DEBUT
CONSTRUCTEUR Maillon(v : type)
DEBUT
valeur <- v
suivant <- NULL
FIN
DESTRUCTEUR ~Maillon()
DEBUT
suivant <- NULL
FIN
FIN
Classe MaillonDouble HERITE DE Maillon
ATTRIBUT PUBLIC
DEBUT
precedent : MaillonDouble
FIN
METHODE PUBLIC
DEBUT
CONSTRUCTEUR MaillonDouble(v : type)
DEBUT
Maillon(v)
precedent <- NULL
FIN
DESTRUCTEUR ~MaillonDouble()
DEBUT
~Maillon()
precedent <- NULL
FIN
PROCEDURE instancier_suivant()
DEBUT
suivant <- NOUVEAU MaillonDouble(1)
FIN
FIN
Dans la méthode instancier_suivant, nous affectons bien l’objet avec le constructeur de la classe MaillonDouble. Vu que le constructeur de la classe MaillonDouble demande une valeur en paramètre, nous sommes dans...
L’objet en Python
1. Objet et classe en Python
La programmation orientée objet est implémentée dans le langage Python. Les classes sont définies grâce au mot-clé class. Pour un code propre, il est demandé de créer un fichier par classe, et un fichier pour le main de notre programme.
# fichier point.py
class Point :
pass
# fichier main.py
from point import Point
mon-point…
Nous créons donc une classe Point dans un fichier point.py que nous importons dans le fichier contenant le main, le fichier main.py.
Pour faciliter l’import de nos classes, les fichiers des scripts doivent tous être dans le même répertoire.
Les attributs d’une classe en Python ne peuvent être déclarés sans être initialisés du fait du typage dynamique du langage. Du fait de la syntaxe de ce langage, les attributs ne peuvent être uniquement déclarés dans les méthodes de la classe. Allons donc étudier comment déclarer les méthodes d’une classe pour en déclarer notamment ses attributs..
2. Utilisation de self pour les méthodes
En Python, pour différencier une fonction d’une méthode, il nous faut placer le mot-clé self en premier paramètre de la méthode, qui est toujours définie par le mot-clé def. Ce mot-clé indique que la méthode est attachée à la classe, self pouvant être traduit comme "soi-même".
Pour appeler une méthode, nous utilisons l’opérateur "." de l’objet instancié.
Lors de l’appel d’une méthode, ce mot-clé self disparait de la liste des paramètres, il n’est obligatoire que lors de sa définition.
Le constructeur est une méthode spéciale qui s’appelle obligatoirement __init__(self, param1, param2…) où les paramètres, or le self, sont optionnels.
Pour appeler le constructeur et donc instancier un objet, il suffit d’appeler le nom de la classe suivi de la liste des paramètres du constructeur (une paire de parenthèses vide si le constructeur n’est défini qu’avec self).
Nous déclarons et initialisons les attributs de la classe dans son constructeur....
Exercices
1. Exercice 1
Modélisez en UML puis avec un algorithme une classe Duree possédant trois attributs privés :
-
le nombre d’heures de la durée ;
-
le nombre de minutes de la durée ;
-
le nombre de secondes de la durée.
Et les méthodes publiques suivantes :
-
Un constructeur par défaut (tous les attributs auront zéro comme valeur) et un constructeur initialisant toutes les valeurs. On vérifiera que les nombres d’heures, minutes, secondes sont bien positifs, dans le cas contraire on considèrera leurs opposés. On fera également les conversions nécessaires pour que les nombres de minutes et de secondes soient strictement inférieurs à 60.
-
Une méthode réalisant l’affichage de la durée (sous la forme 3h10m00s).
-
Une méthode convertissant la durée en un nombre de secondes.
-
Une méthode rajoutant à la durée un nombre de secondes.
Codez par la suite les scripts Python correspondants.
2. Exercice 2
Implémentez dans un algorithme la relation d’héritage entre les classes Animal, Mammifere et Oiseau du diagramme de classes de la figure ci-après.
Diagramme de classes des animaux
La procédure affiche() effectue un affichage console de tous les attributs de la classe.
Codez les scripts Python correspondants.
3. Exercice 3
En Python, codez les classes suivantes :...