Approche Objet
Approche Objet
Approche Objet
Approche orientée-objet
L'approche orientée-objet induit une nouvelle culture du développement logiciel. Elle nécessite une
rupture avec les pratiques de programmation traditionnelles (procédurales).
Dans l'approche procédurale (fonctionnaliste) les données sont séparées des fonctions et procédures
qui les utilisent.
Dans l'approche objet les données et les traitements concernant ces données sont regroupés dans
des entités appelées objets. Un programme objet est un réseau d'objets qui communiquent par l'envoi
de messages pour réaliser un traitement.
données
fonctions
ou
procédures
A. Les types
Le type d'une variable détermine un ensemble de valeurs possibles pour la variable et les opérations
qu'il est possible de faire sur cette variable. Par exemple, l'opération modulo ne peut se faire que sur
les variables de type entier, la multiplication ne peut se faire que sur les types numériques (réel et
entier)…
Un type défini par l'utilisateur permet de représenter des variables structurées, de type enregistrement,
composées d'autres variables appelées champs.
Un type est une sorte de moule qui sert à créer des variables. Chaque variable est un exemplaire, une
occurrence de type.
1
S. Laporte Approche orientée-objet Lycée Louise Michel BTS IG DA
ex:
Soit une structure de donnée permettant de mémoriser les informations concernant un compte bancaire
(simplifié)
Tcompte : enregistrement
numéro: entier
nom : chaîne
solde : réel
Finenregistrement
Une fois un type utilisateur déclaré, on peut déclarer des variables de ce type
Var
cpte1, cpte2 : Tcompte
L'accès aux champs des variables structurées se fait grâce à l'opérateur point '.'
Ainsi, on peut valoriser ces champs
cpte1. nom "Dupond"
cpte1.numéro 1032
cpte1.solde 0
On pourrait aussi déclarer des variables de type Tcompte dans le tas. Dans ce cas, on ne déclare pas
directement la variable mais un pointeur (parfois appelé référence) sur cette variable. Ensuite
seulement, la variable est créée dans le tas par l'opérateur nouveau. L'accès au champ se fait ensuite à
travers le pointeur qui est déréférencé.
Var
pcpte : pointeur sur Tcompte
Début
pcpte nouveau Tcompte
pcpte -> nom "Dupond" //ou (*pcpte).nom = "Dupond"
pcpte -> numéro 1032
pcpte -> solde 0
En programmation procédurale, si nous voulons effectuer des traitements sur les variables,
nous pouvons définir des procédures et fonctions utilisant ces variables. Ces sous-programmes sont
définis en dehors des types de données qu'ils manipulent.
Les variables manipulées doivent être passées en paramètre des sous-programmes qui les manipulent.
L'organisation des programmes procéduraux conduit à une séparation des données et des traitements.
En programmation, une classe peut être considérée comme un cas particulier de structure (au sens du
C/C++) composée de 2 catégories de champs:
nom de la classe
VOITURE
Ex : VOITURE
num_série
marque
couleur attributs
année
démarrer( )
klaxonner( )
arrêter( ) méthodes
Notation algorithmique
Type
Classe Voiture
attributs privés
num_série : chaine
marque : chaine
couleur : chaine
année : entier
méthodes publiques
procédure démarrer( )
procédure klaxonner ( )
procédure arrêter ( )
FinClasse
3
S. Laporte Approche orientée-objet Lycée Louise Michel BTS IG DA
Une classe se déclare comme un type enregistrement auquel on ajoute le prototype des
méthodes applicables aux objets de cette classe.
Lorsqu'une classe est déclarée, on peut déclarer des objets de cette classe. La syntaxe ne pose
pas de problème particulier. Dans cet exemple, on déclare deux objets de type Voiture.
Var
ma_voiture : Voiture //nom de l'objet : Classe
autre_voiture: Voiture
En programmation objet, on accède aux champs (ou membres) de la même manière, avec
l'opérateur point. La seule différence est que les champs d'un objet sont soit des attributs, soit des
méthodes.
objet.attribut
objet.membre
objet.méthode( )
Remarque: Pour distinguer l'accès à un attribut de l'accès à une méthode, on met toujours des
parenthèses après une méthode, même s'il n'y a aucun paramètre.
Ex :
soit ma_voiture un objet de type voiture
Pour accéder à sa couleur on écrit ma_voiture.couleur
Pour appeler la méthode démarrer on écrit ma_voiture.démarrer( )
programmation objet
programmation procédurale
Type
Classe Voiture Tvoiture: enregistrement
attributs privés num_série : chaine
num_série : chaine marque : chaine
marque : chaine couleur : chaine
couleur : chaine année : entier
année : entier Finenreg
méthodes publiques
procédure démarrer( ) //sous-programmes de manipulation
procédure klaxonner ( ) procédure démarrer(une_voiture : Tvoiture )
procédure arrêter ( ) procédure klaxonner (une_voiture : Tvoiture)
procédure arrêter (une_voiture : Tvoiture )
FinClasse
4
S. Laporte Approche orientée-objet Lycée Louise Michel BTS IG DA
En programmation procédurale, pour faire démarrer ma_voiture, il aurait fallu appeler la procédure
démarrer avec le paramètre ma_voiture
démarrer(ma_voiture)
En programmation objet, pour faire démarrer ma_voiture, c'est l'objet ma_voiture qui fait appel à sa
méthode démarrer
ma_voiture.demarrer( )
En programmation objet, tous les traitements sont des méthodes, et sont donc appelées par un objet.
Par exemple, pour démarrer une voiture, il faut un objet voiture, mais il faut aussi qu'un objet
conducteur demande à la voiture de démarrer. L'objet conducteur demande à la voiture de démarrer :
on dit qu'il lui envoie un message.
démarrer
5
S. Laporte Approche orientée-objet Lycée Louise Michel BTS IG DA
Le message sera contenu dans une méthode de la classe Conducteur (expéditeur) et aura la forme
suivante:
une_voiture.demarrer( )
objet destinataire
A la réception de ce message, l'objet voiture va exécuter la méthode démarrer.
1. Principe d'abstraction
C'est un principe qui permet de masquer la complexité des objets à l'utilisateur. C'est grâce à
l'abstraction qu'un utilisateur peut utiliser un objet sans savoir comment il fonctionne (ex: un enfant
sait se servir d'un téléviseur, malgré la complexité de cet appareil). Grâce à l'abstraction, la façon dont
un objet est construit n'a pas d'influence sur la façon dont on l'utilise. Par exemple, c'est grâce à
l'abstraction qu'une voiture diesel se conduit comme une voiture essence, alors que la technologie du
moteur est très différente dans les deux cas.
Exemple: Un téléviseur est un objet très complexe. Pourtant, un enfant de 3 ans sait l'utiliser
car les commandes à connaître sont très simples: allumer, éteindre, changer de chaîne, augmenter ou
baisser le son. L'utilisateur ne sait pas comment est fait un téléviseur mais cela ne l'empêche pas de
l'utiliser correctement. C'est le principe de l'abstraction. L'interface d'un téléviseur est son écran bien-
entendu mais aussi la télécommande et les boutons se trouvant sur le poste.
2. L'encapsulation
Ce principe découle directement du principe d'abstraction. Un objet ne peut être manipulé que
via les méthodes qui lui sont associées lors de sa création. La structure interne de l'objet (ses
attributs) est inaccessible directement: il faut passer par des méthodes qui constituent
l'interface. De ce fait, aucun utilisateur non autorisé ne pourra malencontreusement modifier l'objet
d'une façon interdite. Les attributs, qui ne sont pas accessibles d'un autre objet, sont qualifiés de
privés. Les méthodes, qui peuvent être appelées par d'autres objet (par l'envoi d'un message) sont
qualifiées de publiques.
Ainsi, pour éviter que les utilisateurs ne cassent les composants (ou se fassent mal avec), les
téléviseurs sont contenus dans une boite et les composants sont donc inaccessibles sans démonter
l'appareil.
1 Rappel: la signature d'une méthode est constituée de son nom ainsi que du nombre et du type de ses
paramètres.
6
S. Laporte Approche orientée-objet Lycée Louise Michel BTS IG DA
En programmation, c'est la même chose: l'encapsulation empêche que des bugs ne viennent
accidentellement modifier les données d'un objet. L'encapsulation permet d'augmenter la fiabilité, la
sécurité et l'intégrité des programmes.
L'accès direct aux attributs ne pouvant pas se faire directement, comment y accéder en cas de
besoin? Tout simplement en définissant des méthodes qui permettent d'obtenir l'information voulue.
Ces méthodes (publiques) permettant d'accéder aux attributs (privés) d'un objet sont appelés
accesseurs. Il existe deux types d'accesseurs : les accesseurs en lecture (qui commencent souvent par
get) et les accesseurs en écriture (qui commencent souvent par set).
+ get_couleur()
+ set_couleur()
L'accès direct au numéro de série, à la marque, à la couleur et à l'année d'une voiture ne peut
pas se faire directement. On est obligé de passer par les accesseurs. Seul l'attribut couleur peut être
modifié par l'appel de l'accesseur en écriture set_couleur. Les autres attributs ne peuvent pas être
modifiés et c'est tant mieux car ce sont des attributs qui ne doivent jamais être changés.
EXEMPLE:
Var
une_voiture: Voiture
… ☺
la_couleur une_voiture.couleur la_couleur une_voiture. get_couleur( )
une_voiture.couleur "vert" une_voiture.set_couleur("vert")
une_voiture.marque Renault impossible de modifier la marque d'une voiture
Cas particuliers:
Dans la majorité des cas, les attributs sont privés et les méthodes sont publiques. Mais il est possible
de déclarer aussi des méthodes privées, utilisables seulement par les autres méthodes de la classe.
En Java comme en C++, on peut aussi déclarer des attributs publics (accessibles par d'autres objets).
Mais dans ce cas, le principe de l'encapsulation est violé: ce n'est plus de la programmation objet pure.
7
S. Laporte Approche orientée-objet Lycée Louise Michel BTS IG DA
Lorsque l'on définit une méthode, il faut spécifier à quelle classe elle appartient. Pour cela nous
utiliserons l'opérateur double deux points ::
solde n'est ni une variable locale, ni un paramètre. Mais qu'est-ce donc alors??
En fait, solde représente l'attribut solde correspondant à l'objet de type Tcompte qui reçoit le message
Créditer.
Cet objet peut être désigné explicitement par le mot clé this. This est remplacé au moment de l'appel
par l'objet auquel est adressé l'appel.
this est la plupart du temps implicite. Nous verrons cependant dans un TP qu'il est parfois utile de le
mentionner explicitement.
Fonctionnement
Var cpte1: Tcompte
…
cpte1.créditer(1000) //message créditer envoyé à l'objet cpte1
8
S. Laporte Approche orientée-objet Lycée Louise Michel BTS IG DA
9
S. Laporte Approche orientée-objet Lycée Louise Michel BTS IG DA
Un constructeur est une méthode particulière qui est appelée automatiquement à chaque
"création" d'objet (soit par déclaration, soit par allocation dynamique dans le tas). Cette
méthode permet d'initialiser l'objet créé avec des valeurs valides.
Par convention, un constructeur porte le même nom que la classe et ne renvoie rien. En algorithmique,
on fera précéder cette méthode du mot clé constructeur.
Exemple 1:
Classe personne
attributs privés:
nom: chaîne
prenom : chaîne
age : entier
méthodes publiques:
Constructeur personne( unNom : chaîne, unPrenom: chaîne, unAge: entier )
…
FinClasse
p : personne
mais ceci est inexact car le constructeur, qui est appelé lors de la déclaration d'un objet, possède deux
paramètres. Il faut donc que ces paramètres soient passés d'une manière ou d'une autre au constructeur
lors la déclaration. On va donc utiliser la notation suivante:
Var
p : personne("Dupont", "Toto", 20)
Et pour créer un objet dans le tas, il faut aussi lui passer le nombre de paramètres requis par le
constructeur:
Var
ppers : pointeur sur personne
Début
10
S. Laporte Approche orientée-objet Lycée Louise Michel BTS IG DA
Il n'est pas possible de créer un objet (par déclaration dans la pile ou allocation dans le tas) sans lui
passer le nombre d'argument du constructeur.
Remarque: Il est possible d'écrire une classe sans écrire son constructeur. Dans ce cas, le
compilateur génère un constructeur implicite, qui ne prend aucun paramètres et qui initialise tous les
attributs à la valeur par défaut de leur type (0 pour les numériques, NUL pour les pointeurs, "" pour les
chaînes, etc)
Exemple 2:
Classe fraction
Attributs privés
numérateur : entier
dénominateur : entier
Méthodes publiques
Constructeur fraction(n: entier, d: entier)
Procédure Affiche ( )
FinClasse
Remarques:
- Un constructeur est appelé juste après l'allocation d'un emplacement mémoire pour l'objet.
- Un constructeur est utilisé à 95% pour effectuer des initialisations avec les valeurs qu'il
reçoit en paramètre. Mais le traitement réalisé par un constructeur peut être beaucoup plus
élaboré. Il n'y a aucune restrictions quand aux instructions qui peuvent être réalisées par un
constructeur (excepté qu'un constructeur ne peut rien retourner). Par exemple, un constructeur
peut vérifier que les valeurs des attributs passées en paramètre sont valides (et permettre une
correction de l'erreur le cas échéant)
- Un constructeur qui ne possède aucun paramètre est appelé "constructeur par défaut"
- La création et l'initialisation par le constructeur sont regroupées dans une seule instruction
que l'on appelle instanciation
11
S. Laporte Approche orientée-objet Lycée Louise Michel BTS IG DA
Il est possible de déclarer plusieurs constructeurs différents pour une même classe, afin de
permettre plusieurs manière d'initialiser un objet. Les constructeurs diffèrent alors par leur
signature.
Exemple 2 (suite):
Classe fraction
Attributs privés
numérateur : entier
dénominateur : entier
Methodes publiques
Constructeur fraction(n: entier, d: entier)
Constructeur fraction(nb : entier)
Procédure Affiche ( )
FinClasse
Remarque:
Dans ce dernier cas, comme le numérateur et le dénominateur sont de même type, on ne pourrait pas
définir un troisième constructeur permettant de passer seulement le dénominateur en paramètre. En
effet, un tel constructeur aurait la même signature que le précédent (rappelons que le nom des
paramètres formels ne fait pas partie de la signature)
12
S. Laporte Approche orientée-objet Lycée Louise Michel BTS IG DA
Voilà une classe produit, un programme principal qui l'utilise ainsi que sa sortie d'écran.
- Retrouver les constructeurs manquants (déclaration et implémentation).
- Ecrivez l'implémentation de la fonction prix_ttc et complétez le programme principal pour que
s'affiche en plus le prix toutes taxes de la trousse.
(l'implémentation des autres classes n'est pas demandée)
Classe produit
attributs privés
libellé : chaîne
code_tva : caractère
prix_achat : réel
stock : entier
méthodes publiques
… //constructeurs manquants
Procédure getlibellé( )
Procédure changePrix(nvprix: réel)
Procédure EntréeStock(quantité : entier)
Procédure SortieStock(quantité : entier)
Fonction prix_ttc( )
Procédure Aff_tout( )
FinClasse
Chaque objet d'une classe possède sa propre version de chacun des attributs de la classe. Autrement
dit, un objet ne partage pas ses attributs avec les autres objets de sa classe. Pourtant, dans certains cas,
il est nécessaire de mémoriser une donnée commune à tous les objets d'une classe (par exemple, le
nombre d'objet appartenant à la classe). Dupliquer la donnée dans chacun des objets serait gâcher du
temps et de l'espace mémoire. C'est pourquoi il existe des propriétés spéciales, les attributs statiques
ou attributs de classe, qui ne sont crées qu'en un seul exemplaire commun à tous les objets de la
classe.
Classe Personne
compteur_personnes 3
45 50 55
14
S. Laporte Approche orientée-objet Lycée Louise Michel BTS IG DA
Les attributs statiques, s'il en existe, seront déclarés au début de la section des attributs et sont suivis
du mot clé souligné statique.
Classe Personne
attributs privés
compteur_personnes : entier statique
Nom: chaîne
Prenom: chaîne
Age: entier
méthodes publiques
…
Remarque
on peut aussi utiliser n'importe quel objet de la classe car tous les objets de la classe ont accès à
l'attribut statique. Cependant, pour des raisons de lisibilité, ceci n'est guère conseillé.
Classe Personne
attributs privés
compteur_personnes : entier statique 0
Nom: chaîne
Prenom: chaîne
Age: entier
méthodes publiques
Constructeur Personne(unNom, un Prenom, unAge)
…
FinClasse
Application:
Compléter la classe produit et son implémentation pour qu'elle permette de trouver et d'afficher:
15
S. Laporte Approche orientée-objet Lycée Louise Michel BTS IG DA
Un attribut statique existe en dehors de toute instance de la classe. De la même manière, une méthode
statique peut être appelée indépendamment de tout objet. Pour invoquer une méthode statique, on
utilise le nom de la classe et non celui d'un objet de la classe. Une méthode statique peut donc être
appelée alors qu'aucun objet de la classe n'existe.
Comme une méthode statique existe en dehors de tout objet, elle ne peut manipuler que les
attributs statiques et les autres méthodes statiques de sa classe. Elle ne peut utiliser directement ni
les attributs d'instances (non statiques), ni les méthodes d'instances (non statiques)2.
A. La réutilisabilité
Méditez cet extrait de "Au cooeur de ActiveX et OLE" de David Chappel
" Au cours des 35 dernières années, les concepteurs de matériel informatique sont paasés de machines
de la taille d'un hangar à des ordinateurs portables légers basés sur de minuscules microprocesseurs.
Au cours des mêmes années, les développeurs de logiciels sont passés de l'écriture de programmes en
assembleur et en COBOL à l'écriture de programmes écrire plus grands en C et C++. On pourra parler
de progrès (bien que cela soit discutable", mais il est clair que le monde du logiciel ne progresse pas
aussi vite que le celui du matériel. Qu'ont donc les développeurs de matériels que les développeurs de
logiciels n'ont pas?
La réponse est donnée par les composants. Si les ingénieurs en matériel électronique devaient partir
d'un tas de sable à chaque fois qu'ils conçoivent un nouveau dispositif, si leur première étape devait
toujours consister à extraire le silicium pour fabriquer des circuits intégrés, ils ne progresseraient pas
bien vite. Or, un concepteur de matériel construit toujours un système à partir de composants préparés,
chacun chargé d'une fonction particulière et fournissant un ensemble de services à travers des
interfaces définies. La tâche des concepteurs de matériel est considérablement simplifiée par le travail
de leur prédécesseurs.
La réutilisation est aussi une voie vers la création de meilleurs logiciels. Aujourd'hui encore, les
développeurs de logiciels en sont toujours à partir d'une certaine forme de sable et à suivre les mêmes
étapes que les centaines de programmeurs qui les ont précédés. Le résultat est souvent excellent, mais
il pourrait être amélioré. La création de nouvelles applications à partir de composants existants, déjà
testés a toutes les chances de produire un code plus fiable. De plus, elle peut se révéler nettement plus
rapide et plus économique, ce qui n'est pas moins important."
2 Néanmoins, si elle prend des objets en paramètre, elle pourra utiliser leurs attributs et leurs méthodes
d'instance.
16