Chapitre 7 - Classes et objets

Transcription

Chapitre 7 - Classes et objets
Chapitre 7
Classes et objets
Objectifs
À la fin de ce chapitre, le lecteur sera en mesure :
• de distinguer objets et classes;
• de concevoir des classes simples.
70
Nous arrivons maintenant au chapitre le plus fondamental de ce livre. Il explique, en effet, les
concepts les plus importants d'un langage de programmation : les objets et les classes. Dans
ce chapitre, nous abordons les notions d’objets et de classes ainsi que la conception d’objets
simples.
Qu’est ce qu’un objet, une classe?
La programmation orientée objet (POO) consiste à créer une représentation informatique du
monde réel ou abstrait auquel on s’intéresse. Dans cette représentation informatique, toute
entité du monde est un objet. On appelle classe la structure d’un objet, c’est donc le modèle, le
moule, qui permet de créer un objet.
Une classe est composée de deux parties :
• les attributs : il s’agit des variables qui entreposent les données caractérisant l’objet;
• les méthodes : il s’agit de l'ensemble des actions que l’objet est à même de réaliser.
Conception d'une classe simple
Prenons l'exemple des coordonnées géographiques DMS (degrés, minutes, secondes). Toutes
les coordonnées ont en commun comme caractéristique: un nombre de degrés, de minutes et
de secondes. Les opérateurs qui peuvent être effectués sur une coordonnée sont: la
conversion de DMS à décimale, la conversion de décimale à DMS, l'affichage... C'est à partir
de ces informations que nous allons concevoir un classe CCoordDMS. Ainsi, la classe
CCoordDMS aura 3 attributs: pDeg, pMin et pSec ainsi que 3 méthodes: DecToDMS,
DMStoDec et Afficher. Il est possible de représenter les attributs et les méthodes de la
classe CCoordDMS à l'aide du diagramme suivant:
CCoordDMS
pDeg
pMin
pSec
DecToDMS()
DMStoDec()
Afficher()
Figure 7.1: diagramme représentant la classe CCoordDMS.
71
Création d'une classe
Pour créer un module de classe, il faut sélectionner Module de classe dans le menu
Insertion. Le nom attribué figurant dans la fenêtre des propriétés détermine le nom de la
classe.
Attributs d'une classe
On appelle attribut d'une classe une variable, déclarée à l'intérieur de cette classe. L'ensemble
des attributs constitue l'état de cette classe. Les attributs doivent être déclarés au tout début du
corps de la classe avant qu'aucune méthode ne soit déclarée.
Dans la classe CCoordDMS, les attributs pDeg, pMin et pSec sont définis de la façon suivante:
Private pDeg As Integer
Private pMin As Integer
Private PSec As Integer
Il est pratique courante de déclarer les propriétés comme étant privées.
Initialisation des attributs
L'initialisation d'un objet se fait à l'aide d'une méthode particulière appelée le constructeur. Le
constructeur doit porter le nom Class_initialize, ainsi le constructeur de la classe
CCoordDMS pourrait s'écrire ainsi:
Sub Class_initialize()
pDeg = 1
pMin = 1
pSec = 1
End Sub
72
Accès aux attributs
Comme les propriétés d’une classe sont habituellement privées, il faut définir des méthodes
d’accès. Ces méthodes permettront d’accéder aux attributs de la classe. Ainsi dans notre
exemple:
Property Let Deg(I As Integer)
pDeg = I
End Property
Property Let Min(I As Integer)
pMin = I
End Property
Property Let Sec(I As Integer)
PSec = I
End Property
Normalement, les méthodes d’accès Let devraient contenir une validation des données. Par
exemple, le salaire d’un employé doit être positif:
Property Let Deg(I As Integer)
If I > 180 Or I < -180 Then
MsgBox "Objet CCoordDMS: Erreur"
Else
pDeg = I
End If
End Property
Property Let Min(I As Integer)
If I > 60 Or I < 0 Then
MsgBox "Objet CCoordDMS: Erreur"
Else
pMin = I
End If
End Property
Property Let Sec(I As Integer)
If I > 60 Or I < 0 Then
MsgBox "Objet CCoordDMS: Erreur"
Else
PSec = I
End If
End Property
Les méthodes d’accès Get doivent aussi être définies.
Property Get Deg() As Integer
73
Deg = pDeg
End Property
Property Get Min() As Integer
Min = pMin
End Property
Property Get Sec() As Integer
Sec = PSec
End Property
Déclaration des méthodes
Une méthode est une séquence de déclarations et d'instructions encapsulées ensemble
comme un mini-programme indépendant. Dans une classe, toutes les instructions devront se
situer dans une méthode. Les méthodes sont le lieu de l'action du programme.
Avant de donner un exemple, expliquons comment déclarer une méthode. La déclaration d'une
méthode est l'action par laquelle on définit ce qu'elle fait et sur quelles variables. La déclaration
obéit à la syntaxe suivante:
Public Sub NomMethode([paramètre_1,..., paramètre_n])
Corps_de_la_Methode
...
End Sub
où :
NomMethode :
est le nom qui permet de référencer le sousprogramme.
Il
faut
toujours
choisir
un
nom
significatif et peu encombrant.
paramètres :
sont
une
liste
de
variables
permettant
la
transmission d’informations entre le programme et le
sous programme. Chaque paramètre est formé d'un
type et d'un nom de variable, les paramètres étant
séparés par des virgules.
corps_de_la_Methode :
contient les déclarations des variables locales et les
instructions à exécuter.
Pour terminer conception de l'objet CCoordDMS, les méthodes qui permettent la manipulation
des coordonnées géographiques doivent être déclarées:
Public Sub StringToDMS(S As String)
Dim Tableau() As String
Tableau = Split(S, ":")
74
Deg = Tableau(0)
Min = Tableau(1)
Sec = Tableau(2)
End Sub
Public Sub DecToDMS(D As Double)
Deg = Int(D)
Min = Int((D - Deg) * 60)
Sec = (((D - Deg) * 60) - Min) * 60
End Sub
Public Sub Afficher()
MsgBox Deg & " " & Min & " " & Sec
End Sub
Public Function DMStoDec() As Double
DMStoDec = Deg + Min / 60 + Sec / 3600
End Function
Utilisation des objets
Maintenant que la conception de l'objet CCoordDMS est terminé, il est possible de l'utiliser.
Nous allons donc créer une petite application qui utilise la classe CCoordDMS.
Public Sub testObjetDMS()
Dim Coord As CCoordDMS
Set Coord = New CCoordDMS
Coord.StringToDMS ("10:12:30")
Coord.Afficher
MsgBox Coord.DMStoDec
Coord.DecToDMS (10.23)
Coord.Afficher
End Sub
C'est à la ligne 2 et 4 que l'objet Coord est créé.
Diagramme de classes
Le diagramme de classes est utilisé pour représenter les classes ainsi que les différentes
relations entre celles-ci. Cette représentation fait partie d’un ensemble de diagrammes fournis
75
par le standard UML (Unified Modeling Language). Encore une fois, reprenons l’exemple des
coordonnées géographiques. Le diagramme de classe simplifié suivant représente la classe
CCoordDMS:
Modèle objet d'Excel
Le langage de programmation VBA dépend des applications de Microsoft Office (Word, Excel,
Access...). Chaque application de Microsoft Office possède un ensemble d’objets clairement
définis, organisés en fonction des relations qui les unissent. Cette organisation s’appelle le
modèle objet de l’application. Par exemple, dans Word, les objets manipulés sont des
documents, des paragraphes, des mots... Dans Excel, les objets manipulés sont des
classeurs, des feuilles de calcul, des plages, des cellules... Nous présentons, dans ce chapitre
et à la figure suivante, le modèle objet d’Excel:
76
Collection
Une collection désigne l’ensemble des objets actifs possédant les caractéristiques définies par
la classe. De nombreux objets appartiennent à une collection d'objets, la collection étant ellemême un objet. Par exemple, la collection Workbooks contient tous les objets Workbooks
ouverts. Chaque objet Workbooks comporte une collection Worksheets qui contient tous les
objets Worksheets de ce classeur. Chaque objet Worksheet contient des objets Range.
Objets
En programmation orientée objet, les classes sont en quelque sorte les moules ou les usines à
partir desquels il est possible de créer des objets. Lorsqu’un objet est créé, on parle alors
d'instanciation d'un objet. Une classe contient des propriétés représentant l'état des objets et
des méthodes représentant leur comportement.
Exemple d’objets :
• Excel est un objet Application ;
• un classeur est un objet Workbook ;
• une feuille de calcul est un objet Worksheet ;
• une plage de cellules (qui peut se limiter à une cellule) est un objet Range.
Accès aux objets
VBA permet de faire référence à un objet de différentes façons. Nous illustrons l’accès aux
objets Excel à travers plusieurs exemples. Pour faire référence à une plage de cellules
donnée, il faut utiliser l’objet Range.
Exemple 7.1
Faire référence à la plage de cellules A1:B4.
Range("A1:B4")
Pour faire référence à un objet dans une collection, on peut, soit utiliser le numéro de sa
position dans la collection, soit son nom.
Exemple 7.2
Faire référence à la première feuille de calcul du classeur actif
77
Worksheets(1)
Cette instruction renvoie un objet Worksheet.Workbooks("Classeur1.xls").
Exemple 7.3
Faire référence à la feuille de calcul de nom Feuil1 du classeur de nom Classeur1.xls.
Workbooks("Classeur1.xls").Worksheets("Feuil1")
Cette instruction renvoie un objet Worksheets.
Propriétés des objets
Chaque objet est défini par un ensemble de propriétés qui représentent ces caractéristiques.
Pour faire référence à une propriété d’un objet donné, il faut utiliser la syntaxe
Objet.Propriété.
Exemple 7.4
Sachant que la propriété Value de l’objet Range désigne la valeur de l’objet spécifié. Affecter
la valeur "Steph" à la cellule A1.
Range("A1").Value = "Steph"
Exemple 7.5
Affecter le style gras à la cellule sélectionnée (Font est une propriété de l’objet Range qui
retourne un objet Font contenant les attributs de police (taille, couleur, style, ...) de l’objet
Range.Bold est une propriété booléenne de l’objet Font qui correspond au style gras).
ActiveCell.Font.Bold = True
La propriété ActiveCell de l’objet Application renvoie un objet Range qui fait référence à
la cellule active de la feuille de calcul.
Méthodes
Les méthodes représentent les actions qui peuvent être effectuées par un objet ou que l'on
78
peut appliquer à un objet. Pour faire référence à une méthode, il faut utiliser la syntaxes
Objet.Méthode.
Exemple 7.6
Utiliser la méthode Select de l’objet Range pour sélectionner la cellule A1.
Range("A1").Select
Événements
Un événement associé à un objet permet de déclencher l’exécution d’un sous-programme
lorsque cet événement survient. Un clic souris ou la frappe d’une touche au clavier sont des
exemples d’événements qui peuvent déclencher l’exécution d’un sous-programme. Dans les
chapitres précédents, nous avons déjà associé des sous-programmes à des événements
générés par des contrôles d’une boîte de dialogue.
Explorateur d'objets
L’explorateur d’objets recense l’ensemble des objets disponibles dans VBA, leurs propriétés,
leurs méthodes et les événements qui leur sont associés. Pour ouvrir l’explorateur d’objets, il
faut sélectionner Explorateur d’objets dans le menu Affichage de l’éditeur de Visual Basic.
La fenêtre suivante apparaît :
79
Les différents types de sous-programmes
En VBA, il existe différents types de sous-programmes :
• les sous-programmes;
• les sous-programmes événementiels;
• les fonctions.
Dans les sous-sections suivantes, les trois premiers types de sous-programmes seront décrits.
Sous-programmes
Un sous-programme est une séquence de déclarations et d'instructions encapsulées ensemble
comme un mini-programme indépendant. En VBA, une macro est un sous-programme. La
déclaration d'un sous-programme obéit à la syntaxe suivante :
Sub NomSousProgramme([paramètre_1,..., paramètre_n])
Corps_du_SousProgramme
...
End Sub
où :
80
NomSousProgramme :
est le nom qui permet de référencer le sous-
programme.
Il
faut
toujours
choisir
un
nom
significatif et peu encombrant.
paramètres :
sont
une
liste
de
variables
permettant
la
transmission d’informations entre le programme et le
sous-programme. Chaque paramètre est formé d'un
type et d'un nom de variable, les paramètres étant
séparés par des virgules.
corps_du_SousProgramme : contient les déclarations des variables locales et les
instructions à exécuter.
L’appel d’un sous-programme se fait de la façon suivante :
Call NomSousProgramme([paramètre_1,..., paramètre_n])
Idéalement, un programmeur doit décomposer un programme en petits sous-programmes,
assez petits pour être facilement compris isolément sans avoir à étudier l'ensemble du
programme.
La transmission d’informations d’un sous-programme à un autre s’effectue à
l’aide des paramètres, et non à l’aide de variables globales.
Donnons maintenant un exemple simple.
Exemple 7.7
Écrire un sous-programme qui permet d’afficher des messages de salutation personnalisés:
1
2
3
4
5
6
7
8
Sub Exemple()
Call Salutation("Stephane")
Call Salutation("Anny")
End Sub
Sub Salutation(nom As String)
MsgBox "Bonjour " & nom & "!"
End Sub
Expliquons maintenant ce programme. Il est composé de deux sous-programmes : Exemple
(ligne 1 à 4) et Salutation (ligne 6 à 7). À la ligne 6, on indique que le sous-programme
s’appelle Salutation et accepte un seul paramètre qui est une chaîne de caractères
référencée par nom. Le corps du sous-programme, la ligne 7, permet d’afficher le message de
salutation. La macro Exemple, permet de tester le fonctionnement du sous-programme
Salutation en appelant 2 fois celui-ci avec 2 chaînes de caractères différentes. L’exécution
de ce programme devrait faire apparaître les 2 fenêtres de dialogue suivantes :
81
Passage de paramètres
Les paramètres permettent aux sous-programmes (et aux méthodes) d'envoyer et de recevoir
des messages. Ainsi, envoyer un message à un sous-programme consiste à accomplir le
passage de paramètres. Reprenons l'exemple du sous-programme Salutation:
1
2
3
4
5
6
7
8
Sub Exemple()
Call Salutation("Stephane")
Call Salutation("Anny")
End Sub
Sub Salutation(nom As String)
MsgBox "Bonjour " & nom & "!"
End Sub
Le paramètre nom, déclaré à la ligne 6 dans l'en-tête du sous-programme, permet au sousprogramme Salutation de recevoir un message provenant du programme qui utilise le sousprogramme. Le message envoyé est une chaîne de caractères.
Avant de décrire de façon plus précise le passage de paramètres, il est nécessaire d'expliquer
la différence entre paramètres formels et paramètres effectifs. Examinons le listage précédent.
Les paramètres formels et effectifs sont indiqués en gras. Les premiers à la ligne 2 et 3
("Stephane", "Anny") sont des paramètres effectifs. À la ligne 6 (nom As String) est le
paramètre formel. Le paramètre effectif est donc le message envoyé à la méthode, tandis que
le paramètre formel est une sorte de contenant qui permet de recevoir le message. L'opération
de passage de paramètre peut se résumer simplement par les 2 étapes suivantes:
1. Le paramètre effectif est évalué;
2. La valeur évaluée est assignée au paramètre formel correspondant.
Exemple 7.8
Écrire un sous-programme qui reçoit une chaîne de caractères qui représente des
coordonnées géographiques dans le format DMS et qui extrait les degrés, les minutes et les
secondes. « 25:02:23,56 » est un exemple de coordonnées dans le format DMS.
82
1
2
3
4
5
6
7
8
Sub ExtraireCoord(CoordDMS As String, Deg As Integer,
Min As Integer, Sec As Double)
Dim Tableau() As String
Tableau = Split(CoordDMS, ":")
Deg = Tableau(0)
Min = Tableau(1)
Sec = Tableau(2)
End Sub
Il est également possible de passer un paramètre par valeur en incluant le mot-clé ByVal
dans la déclaration des paramètres. Lorsqu’un paramètre est passé par valeur, la variable
d’origine est copiée dans le sous-programme. Les modifications apportées ensuite aux
paramètres au sein du sous-programme ne sont pas répercutées sur la variable d’origine.
Exemple 7.9
Écrire un sous-programme qui reçoit en paramètre un nombre décimal et qui calcule le carré
de ce nombre.
1
2
3
Sub AuCarre(ByVal x As Double, resultat As Double)
resultat = x ^ 2
End Sub
Sous-programme événementiels
Dans les chapitres précédents, nous avons régulièrement utilisé les sous-programmes
événementiels. Ce sont des sous-programmes associés à un événement qui sont exécutés
lorsque ce dernier survient. Par exemple, le sous-programme CmdButton1_Click() est
exécuté lorsque l'utilisateur presse le bouton CmdButton1 à l'aide de la souris. La syntaxe
d'un sous-programme événementiel est la suivante :
Private Sub Objet_Evenement(paramètres)
...
End Sub
Certains événements n'ont pas de paramètres, alors que d'autres utilisent plusieurs
paramètres.
83
Fonctions
Une fonction est similaire à un sous-programme, mais elle retourne une valeur en affectant
une valeur à son nom dans une ou plusieurs instructions de la procédure. VBA offre la
possibilité de créer ses propres fonctions qui peuvent être utilisées dans Excel comme
n’importe quelle fonction intégrée. La syntaxe est la suivante :
Function NomFonction([paramètre_1,..., paramètre_n]) As Type
...
Corps_de_la_fonction
NomFonction = Expression ‘valeur de retour
...
End Function
où :
NomFonction :
est le nom qui permet de référencer la fonction.
paramètres :
sont une liste de variables permettant la transmission
d’informations entre le programme et la fonction.
Chaque paramètre est formé d'un type et d'un nom de
variable, les paramètres étant séparés par des
virgules.
Indique le type de la valeur que retournera la fonction
Type
après son exécution (Integer, Single, Double,
String…).
corps_de_la_fonction :
contient les déclarations des variables locales et les
instructions à exécuter.
L’appel d’une fonction se fait de la façon suivante :
Variable
= NomFonction ([paramètre_1,..., paramètre_n])
Exemple 7.10
Créer une fonction qui calcule la surface d’un cercle à partir de son rayon:
1. Ouvrir Visual Basic Editor.
2. Insérer un nouveau module et écrire la fonction suivante :
1
2
3
84
Function SurfaceCercle(Rayon As Double) As Double
SurfaceCercle = WorksheetFunction.Pi() * Rayon * Rayon
End Function
L’instruction WorksheetFunction.Pi() permet de faire appel à la fonction =pi()
d’Excel.
3. Retourner dans une feuille de calcul et saisir la formule suivantes dans la cellule B6 :
1
=SurfaceCercle(A6)
La fonction SurfaceCercle peut être utilisée comme n’importe quelle fonction intégrée
d’Excel.
Par
contre,
elle
n'apparaît
pas
dans
la liste
des
macros
(menu
Outils/Macro/Macros…).
Exercices
Exercice 7.1
Écrivez une classe CRectangle qui permettra de représenter un rectangle à partir de sa
largeur et hauteur. De plus, la classe devra permettre de calculer le périmètre et l’aire du
rectangle. Voici les caractéristiques de la classe :
La classe Rectangle doit comporter 2 attributs, soit pLargeur et pHauteur.
Le constructeur doit initialiser les attributs à 0.
Écrivez les méthodes d'accès: let et get.
La classe CRectangle doit comporter deux méthodes: une pour calculer le
périmètre (perimetre) et une pour calculer l’aire (aire).
En vous aidant de la classe CRectangle, créez une macro qui aura l’interface suivante :
85
Exercice 7.2
Écrivez une classe CTemps qui permettra de représenter l’heure :
La classe CTemps doit comporter 3 attributs, soient gHeure, gMinute et
gSeconde.
Le constructeur doit initialiser les attributs à 0.
Écrivez les 6 méthodes d'accès: let et get.
La classe CTemps doit comporter deux méthodes: une pour afficher l’heure
universelle et l’heure standard.
En vous aidant de la classe CTemps, créez une macro qui aura l’interface suivante :
Exercice 7.3
Écrivez une fonction SurfaceRectangle qui permet de calculer la surface d’un rectangle et la
tester dans Excel.
86
Exercice 7.4
Écrivez une fonction qui permet de vérifier que la chaîne de caractères passée en paramètre
est bien un jour de la semaine. Cette fonction doit retourner un booléen.
Exercice 7.5
Écrivez une fonction qui permet de vérifier si une chaîne de caractères passée en paramètre
est un palindrome. Cette fonction doit retourner un booléen. (Voir exercice 6.2)
Exercice 7.6
Faite à nouveau l’exercice 6.2 en utilisant la fonction de l’exercice précédent.
Exercice 7.7
Écrivez 3 fonctions qui calculeront l’aire, la circonférence et le diamètre d’un cercle à partir du
rayon. Testez vos fonctions en les utilisant dans une feuille de calcul Excel (Cellules : A1, A2
et A3).
Exercice7.8
Écrivez une classe CDe qui permettra de représenter un dé. Voici les caractéristiques de la
classe:
La classe CDe doit comporter un attribut, soit pFace.
Le constructeur doit initialiser l'attribut à 0 (Class_initialize).
Écrivez les méthodes d'accès (Let, Get).
La classe CDe doit comporter une méthode: Jouer().
La méthode jouer génère un nombre aléatoire compris entre 1 et 6. Ce nombre aléatoire est
stocké dans l'attribut pFace.
Les instructions suivantes permettent de générer un nombre aléatoire compris en 1 et 10
87
Dim NombreAleatoire As Integer
Randomize
NombreAleatoire = Int((10 * Rnd) + 1)
en utilisant l'objet CDe pour créer un programme qui permet de jouer au dé.
88
89