web-dev-qa-db-fra.com

VBA est-il un langage OOP, et prend-il en charge le polymorphisme?

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?

35
Axel Borja

La POO est assise sur 4 "piliers":

  • check  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.

  • check  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
    
  • check  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")
    
  • nope  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.

82
Mathieu Guindon

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:

  • Encapsulation et abstraction: VBA fournit cela dans une certaine mesure. Les classes peuvent être gardées privées avec des interfaces publiques définies, mais il n'y a aucune disposition pour les constructeurs dans les classes. Les classes ont un 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.
  • Héritage: n'existe pas vraiment dans VBA mais peut être presque répliqué
  • Polymorphisme: peut être atteint dans une certaine mesure via des interfaces (en utilisant 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++.

5
stucharo