User-defined types are a powerful tool for grouping related items of data. Consider, for example, the user-defined type named udtAccount
defined here:
Public Type udtAccount
Number As Long
Type As Byte
CustomerName As String
Balance As Double
End Type
You can declare a variable of type udtAccount
, set the values of its fields individually, and then pass the whole record to procedures that print it, save it to a database, perform computations on it, validate its fields, and so on.
Powerful as they are, user-defined types present the programmer with some problems. You may create a Withdrawal procedure that raises an error if a withdrawal exceeds the balance in the account, but there's nothing to prevent the Balance field from being reduced by other code in your program.
In other words, the connection between procedures and user-defined types depends on the discipline, memory, and knowledge of the programmer maintaining the code.
Object-oriented programming solves this problem by combining data and procedures in a single entity, as shown in Figure 9.5.
Figure 9.5 Objects combine data and procedures
When the user-defined type udtAccount
becomes the Account class, its data become private, and the procedures that access them move inside the class and become properties and methods. This is what's meant by the term encapsulation — that is, an object is a unit (a capsule, if you will) containing both code and data.
When you create an Account object from the class, the only way you can access its data is through the properties and methods that make up its interface. The following code fragment shows how the procedures inside the Account class support encapsulation:
' The account balance is hidden from outside code.
Private mdblBalance As Double
' The read-only Balance property allows outside code
' to find out the account balance.
Public Property Get Balance() As Double
Balance = mdblBalance
End Property
' The Withdrawal method changes the account balance,
' but only if an overdraft error doesn't occur.
Public Sub Withdrawal(ByVal Amount As Double)
If Amount > Balance Then
Err.Raise Number:=vbObjectError + 2081, _
Description:="Overdraft"
End If
mdblBalance = mdblBalance - Amount
End Sub
For the moment, don't worry about how you get the procedures inside the class, or about understanding the syntax of property procedures and private variables. The important thing to remember is that you can define an object that encapsulates and validates its own data.
With the Account object, you never have be concerned about whether you've called the right procedures to update the account, because the only procedures you can call are built into the object.
For More Information "Customizing Form Classes" puts property and method creation into a framework you're already familiar with. Later, "Adding Properties and Methods to a Class" will explain the syntax.
You can read about user-defined types in "Creating Your Own Data Types" in "More About Programming."
For details about Sub and Function procedures, see "Introduction to Procedures" in "Programming Fundamentals."