Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is VBA an OOP language, and does it support polymorphism?

I am actually working on my first VBA project. (come from C++)

I would like to improve an existing VBA project used by a Microsoft Excel workbook by implementing classes and polymorphism.

My problem is:

1 - I read a lot of articles/forums which explain that VBA is not an Object Oriented Programming (OOP) language and do not support Polymorphism.

Some of them propose a workaround using the keyword Implements.

2 - I also found some webpages like this one which explain how to perform OOP and polymorphism in VBA using keywords like Inherits, Overrides, Overridable, MustOverrides.

So my question is :

Is VBA an OOP language, and does it support polymorphism ?

like image 862
Axel Borja Avatar asked Aug 06 '15 14:08

Axel Borja


People also ask

Is Visual Basic an OOP language?

Visual Basic provides full support for object-oriented programming including encapsulation, inheritance, and polymorphism. Encapsulation means that a group of related properties, methods, and other members are treated as a single unit or object.

What language does not support polymorphism?

Explanation: Ada is the language which supports the concept of classes but doesn't support the polymorphism feature. It is an object-based programming language.

What is object-oriented programming in VBA?

Visual Basic supports both procedural and object-oriented programming. Object-oriented programming (OOP) is a programming paradigm that uses objects and their interactions to design applications and computer programs. ( Wikipedia)

What type of language is VBA?

Visual Basic for Applications is a computer programming language developed and owned by Microsoft. With VBA you can create macros to automate repetitive word- and data-processing functions, and generate custom forms, graphs, and reports.


2 Answers

OOP is sitting on 4 "pillars":

  • checkAbstraction - Abstracting logic and concepts can easily be done by defining objects in class modules. Strictly speaking, abstraction is also achieved by using meaningful identifiers and extracting procedural code into methods (class members).

    Here's an example of a procedure written in VBA that demonstrates 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 

    It's easy to tell what this Test procedure does at a glance, because the abstraction level is very high: the implementation details are abstracted away into more specialized objects and methods.

  • checkEncapsulation - Classes can have private fields exposed by properties; classes can be made PublicNotCreatable, effectively exposing types to other VBA projects - and with a little bit of effort (by exporting the class module, opening it in your favorite text editor, manually editing class attributes, and re-importing the module), you can achieve actual read-only types. The fact that there are no parameterized constructors is irrelevant - just write a factory method that takes all the parameters you like and return an instance. This is COM, and COM likes factories anyway.

    Here's an example of how the HotelFinder class from the above snippet encapsulates a Collection object and only exposes it through a Property Get accessor - code outside this class simply cannot Set this reference, it's encapsulated:

     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 
  • checkPolymorphism - Implements lets you implement abstract interfaces (and concrete classes, too), and then you can write code against an ISomething abstraction that can just as well be a Foo or a Bar (given Foo and Bar both implement ISomething) - and all the code ever needs to see is ISomething. Method overloading is a language feature that VBA lacks, but overloading has nothing to do with polymorphism, which is the ability to present the same interface for differing underlying forms (data types).

    Here's an example of applied polymorphism - the LogManager.Register method is happy to work with any object that implements the ILogger interface; here a DebugLogger and a FileLogger - two wildly different implementations of that interface, are being registered; when LogManager.Log(ErrorLevel, Err.Description) is invoked later, the two implementations will each do their own thing; DebugLogger will output to the immediate toolwindow, and FileLogger will write an entry into a specified log file:

     LogManager.Register DebugLogger.Create("MyLogger", DebugLevel)  LogManager.Register Filelogger.Create("TestLogger", ErrorLevel, "C:\Dev\VBA\log.txt") 
  • nopeInheritance - VBA does not let you derive a type from another: inheritance is not supported.


Now the question is, can a language that doesn't support inheritance be qualified as "object-oriented"? It turns out composition is very often preferable to inheritance, which has a number of caveats. And VBA will let you compose objects to your heart's content.

Is VBA an OOP language?

Given all that's missing is inheritance, and that composition is preferable to inheritance, I'm tempted to answer "Yes". I've written full-blown OOP VBA code before (Model-View-Presenter with Unit-of-Work and Repository, anyone?), that I wouldn't have written any differently in a "real OOP" language that supports inheritance.

Here are a few examples, all 100% VBA:

  • Model-View-ViewModel infrastructure & example (proof-of-concept)
  • Full-blown OOP Battleship game with Model-View-Controller (MVC) architecture
  • A reusable progress indicator
  • Model-View-Presenter pattern
  • UnitOfWork with Repository pattern
  • Polymorphic logger
  • Automagic Unit Testing framework

The code in this last link was eventually ported to C#, and quickly evolved into a COM add-in for the VBA IDE that gives you refactorings, better navigation, code inspections, and other tools.

VBA is only as limiting as you make it.

like image 147
Mathieu Guindon Avatar answered Oct 12 '22 15:10

Mathieu Guindon


The short answers are no and no.

VBA is object based, allowing you to define classes and create instances of objects but it lacks the features that would normally be associated with a fully fledged OOP language, for example:

  • Encapsulation and abstraction: VBA provides this to an extent. Classes can be kept private with public interfaces defined, however there is no provision for constructors within classes. Classes have a Class_Inititalize event which can do some construction but cannot take arguments. Passing arguments would require a public factory function workarounds are still required to create a constructor-style design pattern.
  • Inheritance: Doesn't really exist in VBA but can be almost replicated
  • Polymorphism: Can be achieved to an extent through interfaces (using Implements) although the ability to overload functions (for example) doesn't exist and each "overload" would technically require a unique function name. You can work around this by passing in an object as the only parameter to a function or sub and vary the procedure depending on the values of the properties.

So while you can work with objects to an extent and MS Office applications are based around an object model, VBA is not truely an Object Oriented language. Polymorphism cannot be achieved to the extent that you would be familiar with in C++.

like image 31
stucharo Avatar answered Oct 12 '22 16:10

stucharo