MatheX – Licence CC BY-NC-SA 4.0 - https://www.mathexien.com
Objectifs:
- Introduire le principe de POO
- Définir le vocabulaire la POO
- Programmer en paradigme objet sous Python
- Ouvrir sur des aspects plus avancés de la POO
Avant d'introduire la POO, nous allons remobiliser des notions du programme de 1ère.
Rappeler les différents types de données vus en 1ère avec leurs caractéristiques
Proposer une implémentation sous Python de votre classe.
Identifier les difficultés potentielles en terme d'utilisation et d'évolutionRappeler les principes des paradigmes de programmation vus en 1ère
# Vos réponses aux questions ici (et/ou insertion d'images)
Les objets, constitués de leurs données et de leurs actions, sont le coeur de la programmation orientiée objet, plutôt que les fonctions, la séquentialité ou la logique globale.
Les propriétés des objets similaires sont définies par un modèle appelé classe
Chaque classe définit :
Dans le paradigme objet, le principe d'encapsulation permet de cacher les détails d'implémentation de la classe et d'offrir des interfaces d'accès aux objets à travers les méthodes.
Une fois la classe définie ( le model, le moule), on peut créer des des objets appelés aussi "instances de classe" ( des objets concrets créés par le moule)
Par exemple, on peut modéliser différentes voitures à travers une classe Car qui possède les attributs et les méthodes suivants:
Une fois la classe Car crée, on peut l'instancier, c'est à dire créer différents objets représentant une voiture précise:
Proposer une modélisation orientée objet de votre lycée à travers la définition d'attributs et de méthodes pour les classes:
- Lycee
- Classe (du lycée)
- Eleve
- Prof
Cours
Vous pouvez utiliser le formalisme de l'exemple de la classe Car ci-dessus (UML)
# Vos réponses aux questions ici (et/ou insertion d'images)
Python est un langage multipardigme qui permet la programmation orientée objet, même si quelques principes de la POO ne sont pas vraiment respectés.
Un même prorgamme Python peut mélanger plusieurs paradigmes.
Vous avez déjà utilisé la programmation objet dans Python en 1ère, sans forcément le savoir, par exemple lorsque vous utilisiez des méthodes (et non pas des fonctions) sur une liste:
# création d'un objet (d'une instance) de la classe list
myList = [1, 2, 3]
# appel de la méthode append() sur cet objet (cette instance
myList.append(4)
Nous allons maintenant voir comment:
###############################
# Définition d'une classe #
###############################
# on utilise le mot clef 'class' + le 'nom de la classe' (1ère lettre en majuscule) + ':'
class Eleve:
'''classse qui représente un élève.''' # on n'oublie pas la docstring (accessible à travers l'attribut __doc__)
pass
print('\'Eleve\' est de type: ', type(Eleve)) # 'Eleve' est de type: <class 'type'>
print('Documentation de la classe: ', Eleve.__doc__) # Documentation de la classe: classse qui représente un élève
###############################
# Instanciation d'une classe #
###############################
# on appele le constructeur de la classe par le 'nom de la classe' suivi de parenthèses
# éventuellement on ajoute des paramètres entre les parenthèses (voir redéfinition du constructeur)
eleve_1 = Eleve() # une instance de la classe Eleve
eleve_2 = Eleve() # une autre instance de la classe Eleve
print('eleve_1: ',type(eleve_1), id(eleve_1)) # eleve_1: <class '__main__.Eleve'> 140701510390672
print('eleve_2: ',type(eleve_2), id(eleve_2)) # eleve_2: <class '__main__.Eleve'> 140701510393104
#############################################
# Redéfinition du constructeur d'une classe #
# Définition des attributs d'instances. #
#############################################
# le constructeur est une méthode spéciale appelée lors de l'instanciation de la classe
# sa redéfinition permet de définir les attributs des instances de la classe
class Eleve:
'''
classe qui représente un élève.
Attributs
---------
nom (str): le nom de l'élève
prenom (str): le prénom de d'élève
'''
def __init__(self, nom: str, prenom: str): # le mot clef 'self' représente l'objet
''' Initialise les attributs d'un objet élève.'''
self.nom = nom # on affecte à l'attribut nom de cet objet la valeur en paramètre
self.prenom = prenom # on affecte à l'attribut prenom de cet objet la valeur en paramètre
eleve_1 = Eleve('Al-Khwârizmî', 'Muhammad') # une instance de la classe Eleve
eleve_2 = Eleve('Boole', 'George') # une autre instance de la classe Eleve
#############################################
# Définition des méthodes de la classe #
# Accès aux attributs et appel des méthodes #
#############################################
# on rajoute trois méthodes: getNom(), setNom(nom) et infos()
class Eleve:
'''
classe qui représente un élève.
Attributs
---------
nom (str): le nom de l'élève
prenom (str): le prénom de d'élève
Méthodes
--------
getNom() -> str : retourne le nom de l'élève
setNom(nom: str): modifie la valeur de l'attribut nom
infos() : affiche les informations de l'élève
'''
def __init__(self, nom: str, prenom: str):
''' Initialise les attributs d'un objet élève.'''
self.nom = nom
self.prenom = prenom
def getNom(self) -> str :
'''
Retourne le nom de l'élève
Paramètre
----------
None
Retour
------
nom (str): le nom de l'élève
'''
return self.nom
def setNom(self, nom: str):
'''
Modifie la valeur de l'attribut nom
Paramètres
----------
nom (str): le nom de l'élève
Retour
------
None
'''
self.nom = nom
def infos(self):
'''
affiche les informations de l'élève
Paramètre
----------
None
Retour
------
None
'''
print('Nom:', self.nom, 'Prénom:', self.prenom)
eleve_1 = Eleve('Al-Khwârizmî', 'Muhammad')
# accès à un attribut à travers une méthode de type accesseur
print(eleve_1.getNom()) # 'Al-Khwârizmî'
# accès à un attribut directement
# possible en Python mais ne respecte pas le principe d'encapsulation
print(eleve_1.nom)
# modification d'un atttribut à travers une méthode de type mutateur
eleve_1.setNom('Al Khwarizmi')
# modification d'un attribut directement
# possible en Python mais ne respecte pas le principe d'encapsulation
eleve_1.nom = 'Al Khwarizmi'
# appel d'une méthode
print(eleve_1.infos()) # Nom: Al Khwarizmi Prénom: Muhammad
Implémenter en Python les classes
Classe
etEleve
que vous avez modélisé à la mission 1.2 avec au minimum:Les méthodes vues plus haut (accesseur, mutateur, infos)
La comparaison d'un objet de la classeEleve
à un autre élève
L'ajout et la suppression d'un élève dans une classe avec des tests (doublons, existence)
Les attributs que nous avons vu étaient propre à chaque instance de la classe, on les appele des attributs d'instance.
Mais on peut aussi définir des attributs dont la valeur est partagée par toutes les instances de la classe, ainsi que par la classe elle même, on les appele des attributs de classe.
class Eleve:
nb_eleves = 0
def __init__(self, nom, prenom):
self.nom = nom
self.prenom = prenom
Eleve.nb_eleves = Eleve.nb_eleves + 1
# accès ou modification par la classe
Eleve.nb_eleves
Eleve.nb_eleves = 0
eleve_1 = Eleve('Al-Khwârizmî', 'Muhammad')
print(Eleve.nb_eleves) # 1
# accès aussi possible par une instance de la classe
print(eleve_1.nb_eleves) # 1
eleve_2 = Eleve('Boole', 'George')
print(Eleve.nb_eleves) # 2
print(eleve_1.nb_eleves) # 2
print(eleve_2.nb_eleves) # 2
On peut également définir des méthodes de classe accessibles depuis la classe, il suffit de ne pas mettre le paramètre self
class Eleve:
nb_eleves = 0
def __init__(self, nom, prenom):
self.nom = nom
self.prenom = prenom
Eleve.nb_eleves = Eleve.nb_eleves + 1
def getNbEleves():
'''renvoie le nombre d\'élèves'''
return Eleve.nb_eleves
print(Eleve.getNbEleves()) # 0
eleve_1 = Eleve('Al-Khwârizmî', 'Muhammad')
print(Eleve.getNbEleves()) # 1
Pour protéger l'accès direct aux attributs en Python, on peut faire précéder leur nom par deux fois le caractère _
L'attribut devient alors un attribut privé, accessible directement uniquement à l'intérieur de la classe, une instance devra passer par un accesseur.
Idem pour les méthodes.
class Eleve:
def __init__(self, nom, prenom):
self.__nom = nom
self.__prenom = prenom
eleve_1 = Eleve('Al-Khwârizmî', 'Muhammad')
eleve_1.__nom. # erreur lors de l'exécution
Implémenter en Python l'ensemble des classes la mission 1.2
On s'assurera que chaque élève a un identifiant unique