Je travaille actuellement sur mon premier projet [~ # ~] vba [~ # ~]. (provenir de C++)
Je voudrais améliorer un projet [~ # ~] vba [~ # ~] existant utilisé par un classeur Microsoft Excel en implémentant les classes et le polymorphisme.
Mon problème est:
1 - J'ai lu beaucoup d'articles/forums qui expliquent que [~ # ~] vba [~ # ~] = n'est pas un langage de programmation orientée objet ( [~ # ~] oop [~ # ~]) et ne prend pas en charge le polymorphisme.
Certains d'entre eux proposent une solution de contournement en utilisant le mot clé Implements .
2 - J'ai également trouvé des pages Web comme celle-ci qui expliquent comment effectuer OOP et polymorphisme dans VBA en utilisant des mots-clés comme Hérite , Remplace , Overridable , MustOverrides .
Donc ma question est:
Est [~ # ~] vba [~ # ~] an [~ # ~] oop [~ # ~] langage et prend-il en charge le polymorphisme?
La POO est assise sur 4 "piliers":
Abstraction - Il est facile de résumer la logique et les concepts en définissant des objets dans modules de classe. À strictement parler, abstraction est également obtenu en utilisant des identifiants significatifs et en extrayant le code procédural dans les méthodes (membres de la classe).
Voici un exemple d'une procédure écrite en VBA qui démontre abstraction:
Public Sub Test(ByVal checkin As Date, ByVal checkout As Date, ByVal custType As CustomerType)
Dim Finder As New HotelFinder
InitializeHotels Finder
Debug.Print Finder.FindCheapestHotel(checkin, checkout, custType)
End Sub
Il est facile de dire en un coup d'œil ce que fait cette procédure Test
, car le niveau d'abstraction est très élevé: les détails d'implémentation sont abstracted loin dans des objets et des méthodes plus spécialisés.
Encapsulation - Les classes peuvent avoir des champs privés exposés par des propriétés; les classes peuvent être créées PublicNotCreatable
, exposant efficacement les types à d'autres projets VBA - et avec un peu d'effort (en exportant le module de classe, en l'ouvrant dans votre éditeur de texte préféré, en modifiant manuellement les attributs de classe et en réimportant le module), vous pouvez obtenir des types réels en lecture seule. Le fait qu'il n'y ait pas de constructeurs paramétrés est sans importance - il suffit d'écrire une méthode d'usine qui prend tous les paramètres que vous aimez et renvoie une instance. C'est COM, et COM aime les usines de toute façon.
Voici un exemple de la façon dont la classe HotelFinder
de l'extrait ci-dessus encapsule un objet Collection
et l'expose uniquement via un accesseur Property Get
- code en dehors de cette classe ne peut tout simplement pas Set
cette référence, c'est encapsulé:
Private Type TFinder
Hotels As Collection
End Type
Private this As TFinder
Public Property Get Hotels() As Collection
Set Hotels = this.Hotels
End Property
Private Sub Class_Initialize()
Set this.Hotels = New Collection
End Sub
Private Sub Class_Terminate()
Set this.Hotels = Nothing
End Sub
Le polymorphisme - Implements
vous permet d'implémenter des interfaces abstraites (et des classes concrètes aussi), puis vous pouvez écrire du code sur un ISomething
qui peut tout aussi bien être un Foo
ou un Bar
(étant donné que Foo
et Bar
implémentent tous les deux ISomething
) - et tout ce que le code a besoin de voir est ISomething
. La surcharge de méthode est une fonctionnalité de langage qui manque à VBA, mais la surcharge n'a rien à voir avec le polymorphisme, qui est la capacité de présenter la même interface pour différentes formes sous-jacentes (types de données).
Voici un exemple de polymorphisme appliqué - la méthode LogManager.Register
Est heureuse de travailler avec n'importe quel objet qui implémente l'interface ILogger
; ici un DebugLogger
et un FileLogger
- deux implémentations très différentes de cette interface, sont en cours d'enregistrement; lorsque LogManager.Log(ErrorLevel, Err.Description)
est invoqué plus tard, les deux implémentations feront chacune leur propre chose; DebugLogger
sortira dans la fenêtre d'outils immédiate et FileLogger
écrira une entrée dans un fichier journal spécifié:
LogManager.Register DebugLogger.Create("MyLogger", DebugLevel)
LogManager.Register Filelogger.Create("TestLogger", ErrorLevel, "C:\Dev\VBA\log.txt")
Héritage - VBA ne vous permet pas de dériver un type d'un autre: l'héritage n'est pas pris en charge.
Maintenant, la question est, un langage qui ne prend pas en charge l'héritage peut-il être qualifié d '"orienté objet"? Il s'avère composition est très souvent préférable à l'héritage, qui comporte plusieurs mises en garde. Et VBA vous permettra de composer des objets au contenu de votre cœur.
VBA est-il un OOP langage?
Étant donné que tout ce qui manque est l'héritage, et que la composition est préférable à l'héritage, je suis tenté de répondre "Oui". J'ai déjà écrit OOP code VBA auparavant (Model-View-Presenter avec Unit-of-Work et Repository, n'importe qui?), Que je n'aurais pas écrit différemment dans un "vrai POO" langage qui prend en charge l'héritage.
Voici quelques exemples, tous 100% VBA:
Le code de ce dernier lien a finalement été porté en C # et a rapidement évolué en n complément COM pour l'IDE VBA qui vous offre des refactorings, une meilleure navigation, des inspections de code et d'autres outils.
VBA est aussi limité que vous le faites.
Les réponses courtes sont non et non.
VBA est basé sur des objets, vous permettant de définir des classes et de créer des instances d'objets, mais il lui manque les fonctionnalités qui seraient normalement associées à un langage OOP à part entière, par exemple:
Class_Inititalize
événement qui peut faire une construction mais ne peut pas prendre d'arguments. La transmission d'arguments nécessiterait un --- fonction d'usine des solutions de contournement sont toujours nécessaires pour créer un modèle de conception de style constructeur.Implements
) bien que la capacité de surcharger des fonctions (par exemple) n'existe pas et chaque "surcharge" nécessiterait techniquement un nom de fonction unique. Vous pouvez contourner ce problème en passant un objet comme seul paramètre à une fonction ou un sous et faire varier la procédure en fonction des valeurs des propriétés.Ainsi, même si vous pouvez travailler avec des objets dans une certaine mesure et que les applications MS Office sont basées sur un modèle d'objet, VBA n'est pas vraiment un langage orienté objet. Le polymorphisme ne peut pas être atteint dans la mesure où vous seriez familier avec C++.