There is much talk these days about object-oriented programming (OOP) , and many debates over what the term actually means. Generally , OOP perceives objects (which we will look at shortly) to be programmable representations of entities. The objects demonstrate the behavior and characteristics of the entity as methods , properties and events. By using objects to represent entities, we can more easily describe a complex system than by using traditional programming methodologies.
VBA itself is not a full OOP language because it lacks key features. However , VBA has many object-oriented aspects to aid the programmer, some of which we will be considering in this chapter. There are several reasons why object-oriented aspects have been added to many languages, not just the VBA programming language. The main problems are that traditional procedural languages make it hard to reuse code efficiently in other applications and, as applications become larger and more complex, maintaining and modifying procedural code becomes very tricky.
Of course, what puts many people off OOP in the first place is the obscure and esoteric terminology in which it is often described. So let's start by defining our terms.
In the real world we use the word object to describe a whole number of things. A car, a computer, a house - they are all objects. An object can also be a collection of other objects: for example, a car is made up of a chassis, wheels, a transmission system and many other components which are objects in their own right.
The key thing about all these objects is that they encapsulate or contain everything they need to know in order to do what they do, and we don't need to know this information in order to be able to use them. In other words, when the ignition key is turned, the battery, distributor and spark plugs each know what they have to do to start the car; when the brake pedal is depressed, the braking mechanism knows what it has to do to slow the car down - it doesn't have to confer with the battery, for example. We, meanwhile, are not aware of this happening. It is the same when we use an object; its essential characteristics are what matter to us, not how it works underneath, which gives us a lot less to think about.
Likewise, in Access, a form is an object. It knows everything it needs to know in order to do what it does. When you hit the Close button, the form closes itself. When you hit the Minimize button, the form reduces itself to a minimized state. Here we see encapsulation or self-containment at work.
Encapsulation is one of the pillars of OOP along with inheritance , polymorphism, and abstraction . We'll look at each of these terms shortly, but first, we need to look more at what constitutes an object.
All objects have properties . These are simply its characteristics or attributes. Just as a car has a size , weight, and color , objects have their own properties. For example, forms have a Caption property, a Filter property, a DefaultView property, and so on. QueryDef s have properties, too, for example, an SQL property and an Updateable property. You can alter the value of an object's properties, either on the property sheet in design view, or with VBA code.
Methods are behavioral actions of an object. Our car object might have a LightsOn method for turning on the headlights and a LightsOff method for turning them off. In Access, objects have methods for performing actions. For example, among the Database object's methods is the OpenRecordset method for creating a new recordset (refer to Chapter 6 for a discussion of these methods).
Events are notifiable actions or occurrences that can be raised by an object. In our car analogy, a car object may have a NeedToRefuel event that is raised when the fuel level property falls to a given level or value.
We've said that an object encapsulates all of its inner workings so that the outside world doesn't need to worry about them. An object achieves this encapsulation with its interface . The interface of an object is comprised of the object's methods, properties, and events (or, being more precise, those methods, properties, and events that the object makes public; it can keep some private and hidden from other objects). The interface is essentially the view of the object provided to the outside world, and all communication to the object is achieved through the methods, properties and events that make up its interface.
The interface - that is, the properties, methods, and events - of an object are fairly straight-forward. The next OO concept we need to introduce is slightly more unintuitive, but it's vitally important.
A class is a template, or blueprint, for an object. If we stick with our car analogy, then the class could be equated to the technical drawings for the car. At the blueprint stage, we don't actually have a car, just the template, and to create the car we must build it. This gives us an instance of a car, and if we build more cars from the same template, we have multiple instances.
The same holds true for objects. To create the object we instantiate the class, which creates an object based on the class template - just like building a car from the blueprints. An object's interface is defined by the blueprints contained within the class from which it is instantiated. Also, we can create or instantiate multiple instances of the same object from a single class, just as we could produce many identical cars from the same blueprints. This means we can have several objects of the same type, all instantiated (created) from the same class template. It's important to note that although these objects are instances of the same class, they are not the same object - they each exist in their own right.
Generally, if you need multiple instances of an object you have a collection . If you've got lots of money you might have a collection of cars, all stored in a nice air-conditioned building. A collection of objects is similar - it's a way of grouping related objects together, and letting you work on them in a similar fashion.
Classes are examined in more detail in Chapter 13.
Now we understand the concepts of objects, their interfaces (properties, methods, and events), and that you instantiate an object from a class, let's look at the other pillars of OOP - inheritance , polymorphism, and abstraction .
Inheritance provides the ability for a object to take on the functionality of another object, without having to replicate any code. It has two forms: class inheritance and interface inheritance.
Class inheritance is where one class inherits the code of another class. Fully object-oriented languages have class inheritance; VBA doesn't and this is one of the reasons why it is not considered a full object-oriented programming language.
Interface inheritance is where a class inherits only the interface to the class, and then will provide all the functionality to support the interface. In other words, one class inherits a list of properties, methods, and events from another class, but not the actual code within that class which defines how each of the properties, methods, and events actually works. That code must be supplied separately. VBA offers interface inheritance.
Polymorphism refers to having many (poly) implementations of the same thing - we can have one method which can operate on different objects in different ways, but yet achieve the same overall goal. For example, we may have one employee object ( CarSalesperson ) with a phoneCustomer method which is implemented differently from the phoneCustomer method of another employee object ( AccountsClerk ) - the CarSalesperson may use a mobile phone to phone a customer, while the AccountsClerk may use a landline phone to phone a customer. The same named method, phoneCustomer , does the same thing - phone a customer - but they do it in different ways for the two different objects.
Abstraction in an OOP context is a way of describing the essential characteristics of an object that distinguish it from all other objects. This provides us with a hypothetical model of the object, rather than a real object. This provides us with an abstract class that can not be instantiated itself, and hence it can only be used to derived other classes from it (VBA doesn't support class abstraction). Abstraction may also be used in a generic context (real versus abstract), so you need to be alert to the context in which the term is used.
This all seems very complicated, but there are several related reasons why this class and object approach is extremely powerful:
It simplifies complexity by allowing us to define a large and complex system by using smaller sets of interrelated objects.
Designing an application using objects usually means that we are modeling real-life objects, such as orders or products. This allows our program design to naturally map the real world (or domain), enabling us to work more intuitively.
It gives us a vocabulary by which we can more effectively discuss a system or application with co-workers . It is much easier to discuss functionality in terms of a method of an object than in general terms of one of the hundreds of functions which reside in a general code module.
Classes have their own self-contained properties, methods, and events ( encapsulation ), so they are generally self-sufficient. This makes your code more ordered and easier to maintain, as most things to do with that class are stored within the class template. We can, however, have a class that is composed of other classes, which delegates functionality to these contained classes, which themselves encapsulate functionality.
Encapsulation means that code reuse is easy, since you can just copy the class templates and the changes will automatically be reflected in any classes which inherit from the base class you've altered . This is useful when sharing code with others, or when reusing code from old projects, and, over time, reduces development times and costs.