Jusqu’ici, les programmes que vous avez créés l'ont été en programmation impérative (c'est-à-dire une succession d'instructions) et en programmation procédurale ( c’est à dire que chaque programme a été décomposé en plusieurs fonctions réalisant chacune des tâches simples).
À partir des années 1960, un autre type de programmation a été rendu nécesaire par le fait que,
lorsque plusieurs programmeurs travaillent simultanément
sur un projet, il faut éviter les conflits entre les fonctions : la
programmation orientée objet est née.
Le premier langage de programmation initiant une forme de programmation orientée objet fut
Simula, créé à partir de 1962.
Ce langage servait à faciliter la programmation de logiciels de simulation.
Le premier langage de programmation réellement fondé sur la programmation orientée objet fut
Smalltalk 71, créé au début des années 70.
La programmation orientée objet est un paradigme de programmation, c'est-à-dire une autre
manière de voir les notions en programmation.
En programmation procédurale, ce sont les fonctions qui sont au coeur du programme ; elles
s'appliquent à modifier des données.
En programmation orientée objet, ce sont les données qui sont au coeur du programme : celles-ci
vont désormais être protégées et c'est le développeur qui
décide comment elles seront créees, accessibles, modifiées, ... Ah ! pouvoir désormais définir
ses propres objets informatiques en précisant
leurs types, leurs propriétés et les fonctionnalitéss agissant dessus. Que suffit-il ? Un
fiat lux ? Non, il suffit de travailler le cours qui suit !
Cela s'appelle faire ses classes !
Voici un premier exemple concret :
On peut réécrire les phrsaes précédentes avec le vocabulaire de la programmation objet :
Ces actions possibles sur n'importe quel représentant de la classe seront appelées méthodes.
Voici un second exemple, cette fois-ci dans le domaine informatique :
Au chapitre précédent sur les structures de données, vous avez découvert la notion de pile, c'est un type de données.
Pour rappel, voici une représentation d'une pile non vide :
Vous aviez vu comme exemple de pile :
Cet exemple de pile peut être vu vu comme un objet du type pile.
L'élément au sommet d'une pile (non vide), c'est-à-dire celui du haut
de la
pile, est une caractéristique propre d'une pile ;
cet élément peut être vu comme un attribut d'une pile.
Dans l'exemplaire de pile représenté ci-dessus, l'attribut haut
prend la valeur
"Anakin"
.
Vous avez aussi vu que la structure de données pile possède une interface, c'est-à-dire un ensemble d'opérateurs, c'est-à-dire des actions spécifiques aux piles :
vide()
est_vide(P)
empiler(a,P)
depiler(P)
...
Tous ces opérateurs, peuvent être appelés des méthodes.
Cet ensemble de caractéristiques et de méthodes font que le type de données structurées pile est ce que l'on appelle en programmation objet une classe.
Voici un ensemble de définitions, qui vont vous paraître abstraites au départ, mais qui seront clairifées au fil des exemples de ce cours.
Une classe est une structure de données abstraite regroupant :
Un objet est un élément issu d'une classe. On parle aussi d'instance de la classe.
Voici quelques exemples :
Un chien peut être vu comme un objet de la classe Canis lupus familiaris, ayant plusieurs attributs : race, âge, taille, masse, propriétaire, ... Sur cet objet, peuvent s'appliquer plusieurs méthodes : vacciner, tatouer, tondre, ...
Médor, Fido et Pupuce sont des instances de cette classe Canis lupus familiaris.
Un pays peut être vu comme un objet de la classe État, ayant plusieurs attributs : nom, superficie, population, capitale, ... Sur cet objet, peuvent s'appliquer plusieurs méthodes : agrandir, se fractionner, fusionner, ...
La France et la Chine sont des instances de cette classe État.
Une voiture particulière peut être vu comme un objet de la classe voiture, ayant plusieurs attributs : marque, prix, propriétaire, ... Sur cet objet, peuvent s'appliquer plusieurs méthodes : acheter, faire le plein, réparer, vendre, ...
La voiture du proviseur ou de votre enseignant sont des instances de cette classe voiture.
Une autre manière de dire est qu'une classe regroupe des attributs et méthodes communs à un ensemble d'objets :
Encore quelques définitions :
La création d'un objet d'une classe s'appelle une instanciation de cette classe.
La création d'un nouveau pays revient à une nouvelle instanciation de la classe État. Ce nouveau pays est une instance de cette classe État. Cela nécessite de préciser les attributs de ce nouveau pays : donner un nom, spécifier un territoire, une superficie, préciser la capitale, ...
Concrètement, l'instanciation revient à réserver un espace mémoire puis à le remplir par du contenu.
Il existe trois principaux types de méthodes différentes :
Un constructeur est une méthode qui permet l'instanciation. Cette méthode initialise (on dit aussi instancie) l'ensemble des attributs de l'objet.
La déclaration d'indépendance est un constructeur de la classe État. En effet, lors de cette déclaration, les attributs de ce nouveau pays sont précisé : quel nom, quel territoire, quelle superficie, quelle capitale, ...
On considère un jeu dans lequel des cartes sont manipulées. On s'intéresse à l'objet carte à jouer.
JeuDeCartesEnMain
en
précisant deux attributs de cette classe.Comme ces définitions sont assez abstraites de prime abord, voici une analogie pour se faire une image plus concrète de la notion de classe :
Une classe peut être vue comme un moule.
Le moule n'est pas un objet : il sert à créer des objets.
Les instances (ou objets) peuvent être vues comme les pièces sortant du moule.
Le procédé de fabrication d'un objet à partir du moule correspond à une méthode de type constructeur.
La couleur est un exemple d'attribut de l'objet (ou instance). Chaque instance a sa propre valeur pour cet attribut.
Repeindre est un exemple de méthode s'appliquant sur l'objet.
Se briser est une autre méthode s'appliquant sur l'objet.
Si ces notions vous paraissent encore confuses, c'est normal. Mais sachez que vous les manipuler depuis le début sans le savoir car en Python, tout est objet : les fonctions, les types, ...
Vous faites partie d'une société qui crée des jeux vidéo. Dans le projet d'un nouveau jeu, vous devez gérer les personnages. Afin d'éviter tout conflit dans le code produit par les autres collaborateurs, vous écrivez votre code en utilisant le paradigme de programmation objet.
Vous allez devoir commencer par créer la classe Personnage
.
Une classe est définie en Python par le mot-clé class
suivi du NomDeLaClasse
(par convention, contrairement à une variable,
l'initiale est en majuscule et la suite en CamelCase) puis de deux-points :
:
class NomDeLaClasse:
"""
Documentation
"""
Voici le début de la classe Personnage
, avec une succincte documentation :
# pas dans la console mais dans l'éditeur
class Personnage:
"""
Un personnage du jeu vidéo
"""
Vous êtes en train de "définir" le moule général d'un personnage. Reste à définir les attributs d'un personnage.
Pour simplifier, pour l'instant, nous supposons que les personnages ont deux attributs :
Pour construire un personnage à partir (du moule général) de la classe, il vous faut utiliser un
constructeur.
En Python, le constructeur est la méthode :
toujours notée __init__
(utiliser de chaque côté deux tirets du
soulignement),
défini (comme pour les fonctions) par le mot-clé def
et se termine par
deux-points :
,
Les paramètres seront toujours :
le paramètre self
(qui désigne l’objet auquel s’appliquera la
méthode : self
représente l’objet dans
la méthode en attendant qu’il soit créé.),
suivi des paramètres correspondant aux différentes valeurs assignées aux attributs lors de l'instanciation de l'objet.
class NomDeLaClasse:
...
def __init__(self,val_attribut1,val_attribut2,...):
self.nom__attribut1 = val_attribut1
self.nom__attribut2 = val_attribut2
...
Voici le code de la classe Personnage
précédente augmentée du constructeur :
# pas dans la console mais dans l'éditeur
class Personnage: # Définition de la classe
"""
Un personnage du jeu vidéo # Documentation
"""
def __init__(self,genre,experience): # Définition du constructeur
self.genre=genre # premier attribut : le genre (féminin, masculin, autre)
self.experience=experience # deuxième attribut : l'expérience (évaluée par un nombre entier)
A-t-on maintenant le personnage ? Pas encore, il faut appeler (implicitement) le constructeur
pour que l'ordinateur alloue une place
au futur personnage dans sa mémoire pour y caser l'objet et ses attributs.
Pour créer un personnage, nommé ici Thor
, c'est-à-dire une instance de la
classe Personnage
, il suffit, non pas d'appeler le
constructeur __init__
mais directement la classe par son nom.
Il vous suffit donc de saisir :
# dans l'éditeur
Thor = Personnage("masculin",0)
Vous pouvez visualiser le code de la définition de la classe Personnage
et
l'instanciation de l'objet Thor
ci-dessous en ramenant
le curseur au début si besoin puis en faisant défiler étape par étape (avec le bouton "next >")
:
Pour créer une instance d'une classe, il suffit en Python d'utiliser la syntaxe :
nouvel_objet = NomClasse(nom_attribut1,nom_attribut2,...)
Votre personnage Thor
est désormais créé et a sa place dans l'ordinateur (si ce
n'est dans le futur jeu !) comme vous pouvez le voir avec :
# dans l'éditeur
>>> print(Thor)
<__main__.Personnage object at 0x032214D0>
__main__.Personnage object
signifie que Thor
est un objet de la
classe Personnage
: vous avez dès lors son type.
0x032214D0
correspond à la notation héxagésimale (d'où le 0x
du
début) de l'adresse où est stockée l'objet dans la mémoire.
L'exécution du code sur votre ordinateur conduira sûrement à une autre adresse.
Les attributs du personnage créé sont désormais toujours accessibles à l'aide de l'opérateur
d'accessibilité point .
:
Pour accéder aux valeurs des attributs du personnage Thor
:
# dans l'éditeur
>>> Thor.genre
'masculin'
>>> Thor.experience
0
Pour accéder aux attributs d'une instance, il suffit en Python d'utiliser avec l'opérateur
.
en suivant la syntaxe :
valeur = nom_objet.nom_attribut
Berenice une femme d'expérience 1254.
Camille de genre 'autre' et d'expérience 0
Comme a priori, tout nouveau personnage doit commencer avec une expérience nulle, il est possible de définir la valeur par défaut de cet attribut :
class Personnage:
"""
Un personnage du jeu vidéo
"""
def __init__(self,genre,experience=0): # initialisation
self.genre=genre
self.experience=experience
Alors l'appel au constructeur peut se faire avec un seul argument : le genre :
Création simplifiée d'un personnage avec une expérience banale :
# dans l'éditeur
>>> Duc = Personnage('masculin')
>>> Duc.experience
0
On peut encore créer un personnage avec une autre experience en rajoutant un second argument :
# dans l'éditeur
>>> Elsa = Personnage('feminin',42)
>>> Elsa.experience
42
Résumé des bases vues au 2.1 de la programmation d'une classe en Python :
On définit une classe en suivant la syntaxe Les méthodes se définissent comme des fonctions, avec le mot clé
On construit une instance de classe grâce à son constructeur, une méthode
appelée Les méthodes prennent en premier paramètre On définit les attributs d'une instance dans le constructeur de sa classe, en
suivant cette syntaxe : On peut accéder aux attribut d'un objet avec l'opérateur
class NomClasse:
(nom en CamelCase).def
, sauf qu'elles se trouvent dans le corps de la classe.__init__
.self
, l'instance de
l'objet manipulé.self.nom_attribut = valeur
..
en
suivant cette syntaxe : valeur = nom_objet.nom_attribut
Les personnages du jeu vidéo géreront des outils au cours de leur aventure. Ces outils possèdent différents attributs :
Content de vous, vous montrez le début de votre travail à votre chef d'équipe. Il est horifié ! Si l'utilisateur a accès à la représentation interne des classes, il pourrait facilement tricher en donnant par exemple à un personnage une experience de 1000000 !
Il vous parle alors de la notion d'encapsulation :
L'encapsulation est un principe qui consiste à regrouper des données avec un ensemble de méthodes permettant de les lire ou de les manipuler dans le but de cacher ou de protéger certaines de ces données.
Les méthodes et données internes (celles plus ou moins "cacher" à l'utilisateur) sont dites
privées.
Les méthodes et données accessibles à tout utilisateur (celles que les utilisateurs de la
classe connaissent) sont dites publiques.
Certains langages, comme le PHP ou le Javascript vus en première, définissent de manière stricte cette visibilité en fournissant des mots-clés pour caractériser si chaque élément d’une classe est privé ou public.
En Python, il y a une convention de nommage : un attribut privé est toujours préfixé (c'est-à-dire précédé) de deux espaces soulignés (tiret du bas, celui du 8).
attrib1
et attrib2
sont deux attributs publics.__attrib3
et __attrib4
sont deux attributs privés.En Python, lorsque le nom d'un attribut commence par "__", celui-ci est automatiquement renommé ainsi : _nomClasse__nomAttribut. Étant ainsi renommé, il n'est plus aussi aisément accessible depuis l'extérieur de la classe.
class Personnage:
"""
Un personnage du jeu vidéo
"""
def __init__(self,genre,experience=0):
self.genre=genre
self.experience=experience
valeur = nom_objet.nom_attribut
. Que remarquez-vous ?
Il existe un niveau intermédiaire entre privé et public que l'on nomme protégé. En Python, il suffit de préfixer l'attribut
(ou la méthode) d'un espace souligné (tiret du bas ou du 8). Par exemple :
_attrib5 # attribut protégé
.
Contrairement à d'autres langages, en Python, les données protégées sont accessibles normalement
et le préfixe a pour seul objectif
d’informer sur leur nature. Nous n'en parlerons pas plus dans ce cours.
Pour l'interface graphique, le niveau d'expérience doit être accessible mais le joueur ne doit pas pouvoir modifier la valeur directement. Pour pouvoir accéder à la valeur de l'attribut, on créé dans la classe une méthode appelée accesseur.
Par convention, un accesseur commence par le verbe anglais
get
(to get = obtenir = récupérer).
Comme toute méthode, son appel se fera suivant la syntaxe suivante :
valeur = nom_objet.nom_accesseur()
Voici la classe précédente augmentée de la méthode get_experience
qui permet de
récupérer le niveau d'expérience (mais pas de modifier ce niveau) :
class Personnage:
"""
Un personnage du jeu vidéo
"""
def __init__(self,genre,experience=0):
self.genre=genre
self.__experience=experience
def get_experience(self): # self toujours pour désigner l'objet auquel s'appliquera cette méthode
return self.__experience # return ici pour récupérer la valeur souhaitée
Écrivez le code précédent dans un éditeur.
Créez un nouveau personnage Freeda ; vous pouvez lui donner le niveau d'expérience que vous voulez.
Obtenez son niveau d'expérience en utilisant le code suivant :
Freeda.get_experience()
.
Retrouvez-vous la valeur que vous aviez saisie ?
Reprenez la classe que vous avez créé à l'exercice 3 (ici) :
Rajoutez un accesseur permettant de récupérer la masse d'un objet.
Utilisez cette méthode afin de récupérer la masse d'un des objets que vous avez créé lors de l'exercice 3.
Lors du jeu, le niveau d'expérience du personnage doit évoluer : cette expérience doit être
accessible en interne mais pas en externe.
Pour pouvoir modifier la valeur de l'attribut d'un objet, on créé dans la classe une méthode
appelée mutateur.
Par convention, un mutateur commence par le verbe anglais
set
(to set = modifier).
Comme toute méthode, son appel se fera suivant la syntaxe suivante :
nom_objet.nom_mutateur()
Voici ci-dessous la classe précédente augmentée de la méthode set_experience
qui
permet de modifier le niveau d'expérience.
Pour l'instant, cette méthode est publique afin que vous puissiez l'utiliser dans la console.
Il est possible de rendre cette méthode privée en la nommant __set_experience
. Dans
ce cas, vous pourrez modifier le niveau d'expérience
dans le programme (de l'éditeur) mais pas y accéder depuis la console (cf. le programme de
l'exercice 9 du 2.5 accès direct).
class Personnage:
"""
Un personnage du jeu vidéo
"""
def __init__(self,genre,experience=0):
self.genre=genre
self.__experience=experience
def get_experience(self): # self toujours pour désigner l'objet auquel s'appliquera cette méthode
return self.__experience # return ici pour récupérer la valeur souhaitée
def set_experience(self,valeur): # valeur sera le niveau niveau de l'experience
self.__experience = valeur
Remarquez qu'aucun return
n'est nécessaire ici pour le mutateur ; la valeur de
l'expérience est changée sans être renvoyée.
Un peu comme si vous modifiiez une variable globale.
get_experience()
.
Garou.set_experience(10)
.Reprenez la classe que vous avez créé à l'exercice 3 (ici) :
Résumé des informations vues du 2.2 au 2.4 de la programmation d'une classe en Python :
L'encapsulation est un principe qui consiste à cacher ou protéger certaines
données des objets. Un attribut ou une méthode peut être :
public : c'est-à-dire accessible à tout utilisateur, privé : c'est-à-dire accessible "seulement" dans le code de la
classe. Un accesseur est une méthode de la classe qui retourne la valeur d’un
attribut d'un objet. Un accesseur est défini dans la classe, par exemple en suivant cette syntaxe
: Un mutateur est une méthode de la classe qui modifie la valeur d’un attribut
d'un objet. Un mutateur est défini dans la classe, par exemple en suivant cette syntaxe :
Un attribut ou une méthode privée s'obtient avec deux soulignements
__
en suivant cette syntaxe :
__nom_attribut
ou __nom_methode()
def get_attribut(self):
.def get_attribut(self,nouvelle_valeur):
.
Il est possible d'insérer dans une classe toute méthode jugée utile.
Dans notre exemple, il serait intéressant :
d'insérer une méthode rencontre
qui fait progresser l'expérience du
personnage en fonction
des rencontres qu'il vit,
faire en sorte que l'utilisateur ne puisse pas modifier l'expérience de son personnage
par simple appel de la méthode set_experience()
On peut supposer que chaque rencontre augmente l'expérience d'un nombre aléatoire compris entre
10 et 20. En Python, cela nécessitera l'utilisation
de la bibliothèque random
. Ainsi, le début du programme devra désormais commencer
par l'habituel :
from random import *
La méthode rencontre
conduit au tirage aléatoire du gain d'expérience puis à
l'appel de la méthode désormais rendue privée __set_experience
.
from random import *
class Personnage:
... # le début n'est pas modifié : il est à reprendre des exemples précédents par copier-coller.
def __set_experience(self,valeur): # méthode désormais privée car seul le programme y accède pour modifier la valeur : d'où le nom commençant par __
self.__experience = valeur
# Autre méthode :
def rencontre(self):
""""fait évoluer aléatoirement l'expérience lors d'une """
n = randint(10,20) # tirage aléatoire d'un entier entre 10 et 20 (inclus)
self.__set_experience(self.get_experience()+n) # appel de la méthode __set_experience, agissant sur l'objet sur lequel elle s'appliquera (self).
# Le nouveau niveau d'expérience est l'ancien (obtenu avec self.get_experience() ) augmenté de n.
Complétez puis exécuter le programme complet définissant la classe Personnage.
Créez un nouveau personnage sans expérience initiale puis faites lui vivre une première rencontre.
Observez l'évolution de son expérience.
Faites vivre au personnage une seconde rencontre et observez l'évolution de son expérience.
Pouvez-vous par un appel direct au mutateur __set_experience()
modifier
l'expérience de ce personnage ?
Pour l'instant deux classes ont été créées de manière indépendante : la classe
Personnage
et celle Outil
.
L'objectif est désormais de faire un lien entre ces deux classes.
Pour cela, nous allons utiliser ces classes comme un module simple utilisable par différents programmes, tout comme vous utilisiez des bibliothèques déjà construites à l'intérieur de programme. On parle alors de modularité.
En pratique, vous pouvez :
créer un fichier par classe.
modifier ainsi une classe (donc un fichier) sans avoir à modifier les autres.
partager le travail en équipe en se répartisant les classes (donc les fichiers) à réaliser.
Pour lier les deux classes déjà construites, nous allons successivement :
Construire la classe Outil
à l'intérieur d'un fichier spécifique,
Importer cette classe Outil
dans un nouveau programme qui correspondra
à la classe Personnage
précédente modifiée.
Ce programme correspondra à un nouveau fichier,
Créer un programme principal qui importera la seule classe Personnage
.
Ce programme correspondra grosso modo au programme accessible à l'utilisateur.
Voici le détail de ce qui est à faire :
Créez un fichier nommée outil.py
qui contient le code de la classe
Outil
.
Il vous suffit d'y mettre comme contenu le code obtenu à la fin de l'exercice 8 (cf.
lien direct).
Créez un nouveau fichier nommé personnage_avec_outil.py
.
Y mettre le contenu de la classe Personnage
obtenu à la fin de
l'exercice 9 (cf. lien direct).
Comme quelques modifications sont nécessaires pour lier les deux classes,
afin d'éviter les confusions, renommer la classe comme
PersonnageAvecOutil
.
Rajouter en deuxième ligne le code suivant :
from outil import *
Ce code permet d'importer les fonctions présentes dans le fichier outil.py,
c'est-à-dire d'utiliser les méthodes de la classe Outil
.
Désormais, les deux classes sont liées.
Créez un fichier main.py
. Ce fichier sera le programme que
l'utilisateur exécutera directement.
Dans ce fichier main.py
, coller le code suivant :
# importation des fonctions présentes dans le fichier personnage_avec_outil.py, c'est-à-dire des méthodes de la classe PersonnageAvecOutil
from personnage_avec_outil import *
# gestion de l'affichage de la saisie du genre par l'utilisateur
genre = input("""
Saisir la lette correspondant au genre désiré pour votre personnage :
M : si vous voulez une héros de genre masculin,
F : si vous voulez une héroïne de genre féminin,
A : si vous désirez un personnage sans genre déterminé
""")
genre = genre.upper() # pour s'assurer que la lettre saisie est en majuscule
# Création du nouveau personnage, appelé ici par défaut hero
if genre=='F':
hero = PersonnageAvecOutil('feminin')
elif genre=='M':
hero = PersonnageAvecOutil('masculin')
elif genre=='A':
hero = PersonnageAvecOutil('autre')
else :
print("erreur de saisie dans le choix du genre")
# Affichage d'une caractéristique du personnage créé :
print("Votre personnage a comme niveau d'expérience {}.".format(hero.get_experience()))
Remarquez que la méthode get_experience()
de la classe
PersonnageAvecOutil
est directement utilisable. En exécutant le programme de ce fichier, vous devez voir apparaître dans la console :
>>>
Votre personnage a comme niveau d'expérience 0.
Maintenant que les deux classes sont liées, il est possible de modifier ou de créer des méthodes.
On veut désormais que tout personnage possède un objet, unique pour simplifier pour
l'instant.
Pour cela, on considère que le personnage possède un nouvel attribut, nommé
objet
, qui correspond à l'outil en main.
On veut désormais que tout personnage nouvellement créé commence avec un seul outil :
un simple bâton de marche, de masse 0.5 kg et que l'on peut tenir à une seule main.
Pour cela, modifiez comme ci-dessous le script de la méthode __init__
de la classe PersonneAvecOutil
du fichier personnage_avec_outil.py
:
def __init__(self,genre,experience=0):
self.genre=genre
self.__experience=experience
self.objet = Outil(0,0.5) # ligne à rajouter
Cette ligne rajoutée fait appel au constructeur de la classe Outil
,
constructeur importé grâce au code de la première ligne
from outil import *
.
On désire maintenant obtenir un accesseur pour ce nouvel attribut
objet
.
On veut qu'il nous renvoie la masse et le nombre de mains nécessaires à son
utilisation.
Pour le créer dans la classe PersonneAvecOutil
(donc dans le fichier
fichier personnage_avec_outil.py
),
il suffit d'utiliser les méthodes déjà existantes dans la classe Outil
.
Le script suivant, qui permet d'obtenir un tel accesseur, est à copier en fin de
fichier personnage_avec_outil.py
:
# méthode faisant appel à la classe Outil :
def get_objet(self):
"""accesseur des caractéristiques masse et nombre de mains de l'objet"""
masse = self.objet.get_masse()
main = self.objet.get_main()
return masse,main
les méthodes get_masse()
et get_main()
sont
celles de la classe Outil
importée.
elles s'appliquent sur l'instance self.objet
qui correspond
à l'attribut objet
du personnage courant
(appelé avec le mot-clef self
).
On désire que lors de la création d'un nouveau personnage, s'affiche le nom de l'objet avec la valeur de ces attributs de masse et de nombre de mains nécessaires.
Pour cela, il suffit de rajouter les deux lignes suivantes en fin du programme
principal (du fichier main.py
) :
# Découverte des caractéristiques de l'objet en main du héros ou de l'héroïne :
print("Vous commencez avec un bâton de marche de masse {} que vous pouvez tenir à {} main.".format(hero.get_objet()[0],hero.get_objet()[1]))
Notez bien que :
bien que la classe Outil
ne soit pas directement importée
dans la fichier main.py
,
on peut accéder aux attributs de l'outil.
cet accès se fait grâce à l'accesseur nouvellement créé, qui lui est
importé de la classe PersonnageAvecOutil
grâce à la ligne déjà présente : from personnage_avec_outil import *
.
Si vous exécutez ce programme main.py
, vous verrez s'afficher dans la
console :
>>>
Votre personnage a comme niveau d'expérience 0.
Vous commencez avec un bâton de marche de masse 0.5 que vous pouvez tenir à 1 main.
Résumé de cette partie :
On peut décomposer un projet en plusieurs classes dont le script est écrit
dasn des fichiers séparés, On peut utiliser une classe dans une autre classe par simple import de
fichier, L'utilisateur aura un accès direct à un fichier (ici L'utilisateur utilise indirectement l'ensemble des classes : en instanciant
un personnage de la classe On peut ainsi partager le travail de codage entre plusieurs personnes sans
risque de perturbation, une fois l'architecture globale des fichiers conçue.
main.py
:
il ne voit pas comment est conçue l'architecture globale du projet
ni l'ensemble des classes qui le composent.PersonnageAvecOutil
,
il instancie aussi un outil de la classe Outil
.
Vous devez créer une nouvelle méthode, nommée decouverte
dans la classe
PersonnageAvecOutil
qui modélise la découverte
d'une nouvel objet par le joueur, objet dont le niveau requis, la masse et la nombre
de mains sont donnés comme paramètres de cette méthode.
Cette méthode conduira au remplacement de l'outil en main (celui de l'attribut
objet
) par le nouveau dans le seul cas où
le personage possède un niveau d'exprérience suffisant pour cela.
De plus, deux affichages diférents sont attendus dans la console :
Nouvel objet
s'il y a eu changement d'outil,
Dommage, il faut encore progresser en niveau
sinon.
Testez votre code en lançant le programme main.py
puis en saisissant,
par exemple, dans la console :
>>> hero.decouverte(10,1.23,2)
Vous devez obtenir comme affichage :
>>> hero.decouverte(10,1.23,2)
Dommage, il faut encore progresser en niveau
Testez le cas de la découverte d'un objet que votre personnage peut posséder vu son niveau d'expérience.
Vous pouvez vous amuser à rajouter d'autres méthodes (voire même des attributs) pour poursuivre le jeu.
Outil
que le nombre d'outils que
votre personnage peut avoir.
Évidemment, vos aurez sûrement alors à modifier les méthodes liées à ces attributs.
Voici une liste de sites traitant de la programmation orientée objet :