Polymorphisme avec VBA: implémentation d'interface
Bonjour,
En fait le fil de messages originel est à rechercher sur le forum Access/VBA Access qui évoquait la problématique de l'héritage pour les classes développées en VBA: Héritage, possible ou non?
Donc la discussion a quelque peu dévié sur la question du polymorphisme, et s'est retrouvé déplacée sur le forum Général VBA.
_____---====OOOOO====---
Au risque de déborder un peu sur le sujet originel, je souhaite préciser comment on met en œuvre le polymorphisme en VB/VBA.
Citation:
Envoyé par
Pierre Fauconnier
Ce ne serait pas l'inverse ? ... Implements permet "une sorte" d'héritage, mais pas le polymorphisme... (enfin, c'est ce qu'il me semble...)
D'abord il faut s'entendre sur la signification de polymorphisme.
Aussi, je me reposerai sur Wikipédia avec un court extrait ci-dessous et la suite sur la page de Wikipédia illustrée par un exemple:
Citation:
Envoyé par Wikipédia
En informatique, le polymorphisme est l'idée d'autoriser le même code à être utilisé avec différents types, ce qui permet des implémentations plus abstraites et générales.
Je reprends l'exemple de la page de Wikipédia (merci de vous y reporter) en l'adaptant au VB/VBA.
Une classe-interface cForme décrit les méthodes à implémenter pour toutes les "formes" géométriques:
Code:
1 2 3 4 5
| Option Explicit
Public Function Aire() As Double
Aire = 0
End Function |
Une classe cCarré décrit les formes de type Carré et implémente les méthodes d'une "forme" géométrique.
L'utilisation du mot-clé Implements (dans la partie déclaration du module de classe) spécifie qu'une classe implémente l'interface publique (méthodes et propriétés) d'une autre classe.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Option Explicit
Implements cForme
Private p_nCôté As Double
Private Function cForme_Aire() As Double
cForme_Aire = p_nCôté * p_nCôté
End Function
Public Property Get Côté() As Double
Côté = p_nCôté
End Property
Public Property Let Côté(n As Double)
p_nCôté = n
End Property |
Une classe cCercle décrit les formes de type Cercle et implémente les méthodes d'une "forme" géométrique:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Option Explicit
Implements cForme
Private p_nRayon As Double
Private Function cForme_Aire() As Double
cForme_Aire = CDbl(3.1415926535) * p_nRayon * p_nRayon
End Function
Public Property Get Rayon() As Double
Rayon = p_nRayon
End Property
Public Property Let Rayon(n As Double)
p_nRayon = n
End Property |
Dans un module de code, on spécifie la fonction AireTotal() qui reçoit en paramètre une collection d'objets "formes" et retourne la somme des aires de ces objets.
C'est ici que le polymorphisme rentre en jeu puisque, selon le type de "forme", la fonction fait toujours appel à la bonne méthode de calcul Aire(). Tout type de "forme" géométrique qui implémente la classe/interface cForme peut être ajouté sans nécessiter une modification de la fonction AireTotal().
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13
| Public Function AireTotal(collFormes As Collection) As Double
Dim oForme As cForme
Dim nTotal As Double
nTotal = 0
For Each oForme In collFormes
' la fonction "sait" automatiquement quelle méthode Aire() appeler
nTotal = nTotal + oForme.Aire()
Next oForme
AireTotal = nTotal
End Function |
Enfin, on peut aussi coder une procédure pour tester tout ça:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Public Sub TestFormes()
Dim oCarré As New cCarré
Dim oCercle As New cCercle
Dim collFormes As New Collection
Dim nTotal As Double
oCarré.Côté = 3.4
oCercle.Rayon = 5.1
collFormes.Add oCarré
collFormes.Add oCercle
nTotal = AireTotal(collFormes)
Debug.Print nTotal
End Sub |
A l'usage, l'implémentation d'interface permet:
(1) de coder des procédures "génériques" qu'il ne sera pas nécessaire de modifier pour prendre en compte de nouveaux "sous-types" (exemple la fonction AireTotal()),
(2) d'obtenir un code plus robuste parce que les appels de méthodes sont vérifiés à la compilation (liaison dynamique "late binding" mais avec la rigueur du contrôle de type).
Merci aux courageux et curieux qui ont lu jusqu'au bout. ;)
_