Abstraction - 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.
Encapsulation - 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
Polymorphism - 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")
Inheritance - VBA does not let you derive a type from another: inheritance is not supported.
“VBA是一种面向对象的语言吗?”鉴于缺少继承,并且组合优于继承,我倾向于回答“是”。我以前编写过完整的OOP VBA代码(Model-View-Presenter with Unit-of-Work and Repository),我在支持继承的“真正的OOP”语言中也不会写得不同。
Implements
的一些帖子:Here。 - Daniel DušekImplments
)的好例子:http://www.cpearson.com/excel/Implements.aspx - Daniel Dušek