Programmation Orientée Objet
1) Introduction : Programmation procédurale, programmation orientée objet⚓︎
1.1) La notion d’objet et de classe⚓︎
Jusqu’ici, les programmes ont été réalisés en programmation procédurales, c’est à dire que chaque programme a été décomposé en plusieurs fonctions réalisant des tâches simples.
Cependant lorsque plusieurs programmeurs travaillent simultanément sur un projet, il est nécessaire de programmer autrement afin d’éviter les conflits entre les fonctions pouvant porter le même nom sans le savoir. On utilise pour cela la Programmation Orientée Objet.
Note
Un objet se caractérise par :
- son identité : son nom
- son état : défini par la valeurs de ses attributs
- son comportement : défini par ses méthodes
1.2) Classe : un premier exemple avec le type list⚓︎
1 2 3 4 |
|
Type de l'ojet liste : <class 'list'\>
Contenu de l'objet liste : [1, 3, 5]
Une action possible sur les objets de type liste est le tri de celle-ci avec la méthode nommée sort()
.
La syntaxe est : nom_objet.nom_méthode()
, comme avec la méthode de tri : liste.sort()
.
Rappel sur le vocabulaire dédié.
- Les variables d'une classe s'appellent des attributs
- Les fonctions d'une classe s'appellent des méthodes
- Un objet est une instance d'une classe
- La création de l'objet s'appelle l'instanciation d'une classe
- La méthode exécutée automatiquement lors de l'instanciation d'un objet s'appelle le constructeur
- On dit que les attributs et les méthodes sont encapsulés dans la classe.
1.3) Un peu d'histoire.⚓︎
La programmation orientée objet, qui fait ses débuts dans les années 1960 avec les réalisations dans le langages Lisp, a été formellement définie avec les langages Simula (vers 1970) puis SmallTalk.
Puis elle s’est développée dans les langages anciens comme le Fortran, le Cobol et est même incontournable dans des
langages récents comme Java.
2) Création d'une classe pas à pas.⚓︎
2.1) Un constructeur.⚓︎
On va créer une classe simple, la classe Carte correspondant à une carte d’un jeu de 32 ou 52 cartes.
Par convention, une classe s’écrit toujours avec une majuscule.
1 2 3 4 5 |
|
L'attribut self
La variable self , dans les méthodes d’un objet, désigne l’objet auquel s’appliquera la méthode.
Elle représente l’objet dans la méthode en attendant qu’il soit créé.
Création d'une instance de la classe carte :
1 2 |
|
Accès aux attributs de l'objet carte1 : on utilise un point, on peut le lire de droite à gauche en remplaçant le point par "de" :
* carte1.valeur
: valeur de carte1
* carte1.couleur
: couleur de carte1
1 |
|
5 de carreau
1 2 3 4 |
|
3 de trefle
9 de coeur
2.2) Encapsulation : les accesseurs ou "getters".⚓︎
L'encapsulation désigne le fait de regrouper l'ensemble des attributs et des méthodes dans une même classe.
But de l'Encapsulation :
* simplifier la vie du programmeur qui les utilise;
* masquer leur complexité (diviser pour régner - pensez à la méthode list.sort()
dont l'écriture est très complexe);
* permettre de modifier une classe sans changer les programmes qui l'utilisent;
* la liste des méthodes devient une sorte de mode d’emploi de la classe.
Les accesseurs - getters
On ne va généralement pas utiliser la méthode précédente nom_objet.nom_attribut
pour d’accéder aux valeurs des
attributs car on ne veut pas forcément que l’utilisateur ait accès à la représentation interne des classes.
Pour utiliser ou modifier les attributs, on utilisera de préférence des méthodes dédiées : les accesseurs (ou getters).
Le nom d’un accesseur est généralement : getNom_attribut()
.
La méthode __str__(self)
renvoie une chaîne de caractère représentant l'objet. On y accède automatiquement lors de l'exécution de l'instruction print(nom_de_l_objet)
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
(10, 'pique')
10 de pique
Exercice 1⚓︎
Créer deux autres méthodes permettant de récupérer la valeur de la carte et la couleur avec les "getters" (accesseurs) :
getCouleur()
et getValeur()
.
Les utiliser pour afficher : carte1 est un 10 de pique
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
2.3) Modifications contrôlées des valeurs des attributs : les mutateurs ou "setters"⚓︎
On va devoir contrôler les valeurs attribuées aux attributs. Pour cela, on passe par des méthodes particulières appelées mutateurs (ou "setters") qui vont modifier la valeur d’un attribut d’un objet.
Le nom d’un mutateur est généralement : setNom_attribut()
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|
(7, 'coeur')
la valeur de la carte doit être un nombre compris entre 2 et 14
(7, 'coeur')
(10, 'coeur')
10 de coeur
Exercice 2⚓︎
- Créer le mutateur de l’attribut couleur sous la forme
setCouleur(self,c)
. - Contrôler l'attribut pour qu'il puisse prendre uniquement une des 4 couleurs.
- Créer une carte
carte3
, un Roi de coeur. - Modifier la couleur de la carte
carte3
en la passant à pique. Afficher la carte. - Tenter de modifier la couleur de la carte
carte3
en la passant à losange. Afficher la carte.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
3) Notion d'agrégation⚓︎
Lorsqu'on a écrit la classe Carte et qu'on veut l'utiliser dans un programme, on va utiliser la notion de module python. Autrement dit on va sauvegarder le code de la classe Carte
dans un fichier carte.py et importer le module carte dans le nouveau programme. Pour cela, on va :
1. Enregistrer le code de la classe Carte
dans un fichier carte.py, dans le même dossier.
2. Commencer le nouveau programme en tapant : from carte import *
.
Par exemple, on va créer un jeu de carte qui utilise la classe Carte.
Il pourra avoir 32 ou 52 cartes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
|
Excercice 4⚓︎
Importation du module carte.py
1. Enregistrer le code de la classe Carte
dans un fichier carte.py, dans le même dossier.
2. Commencer le nouveau programme en tapant : from carte import *
.
Implémentation du constructeur
- Modifier la ligne de code pour s'assurer que
self.nombre_cartes
est égale à 32 ou 52, sinon l'imposer à 32. - Ajouter la ligne de code qui appelle la méthode
creer_paquet()
qui créer le jeu de cartes. - Implémenter la méthode
creer_paquet()
. Tester son fonctionnement. - Créer la méthode
__str__(self)
qui permet d'afficher les cartes du jeu. Servez vous de la méthode__str__(self)
de la ClasseCarte
. - Instancier un jeu de 32 cartes
jeu1
et afficher les cartes qu'il contient avec l'instructionprint(jeu1)
.
Compléter les autres méthodes de la classe.
- Implémenter les accesseurs et tester leur fonctionnement.
- Implémenter la méthode
melanger_jeu(self)
et tester son fonctionnement. Utiliser la méthodelist.shuffle()
. - Implémenter la méthode
distribuer_une_carte(self)
et tester son fonctionnement (en particulier le fait que la carte soit supprimée du paquet).