You can create custom properties as part of the functionality that your Class
object provides to calling code. You can implement these custom properties either as Public variables
of the Class or by using special Property Let/Set and Property Get procedures.
Implementing Properties as Public Variables
A Public variable in a class module automatically implements a property of the class.
You can declare Public variables in a class module in the same way you declare Public variables
for other modules such as forms and standard (BAS) modules. To add a property called "Name"
to a class, you just write the following lines in the General Declarations section of a class
module:
Public Name as String
This is, of course, the same way that forms use Public variables. Therefore,
when calling code accesses your class by instantiating an object, the caller can manipulate the properties
of the object it has declared with the standard object.property syntax, as in the following
line:
objMine.Name = "Geryon"
and later
MsgBox objMine.Name
The basic advantage of implementing an object property with a Public variable is
that it is very easy to do. The downside is that
-
You can't create a read-only property, because Public variables are always writable.
You have no way of triggering an automatic action when the property is manipulated
(such as hiding an object when a Visible property is set to False).
Different simultaneous instances of a class share the same Public variables, and
thus cause all sorts of possible confusion in your calling code.
To get around these disadvantages, you must give up the idea of using Public variables
to implement class properties and instead use Property Let/Set and Property Get procedures
as described in the following sections.
Implementing Properties with Property Procedures
With some additional work, you can overcome the disadvantages of properties
implemented as Public variables.
You can use the special Property procedures instead. To implement the Name property
of a class with Get and Let procedures, you put the code shown in Listing 12.2 in your class
module rather than a Public variable declaration.
LISTING 12.2
IMPLEMENTING A CLASS PROPERTY WITH Property Get AND Let PROCEDURES
[General Declarations section of Class]
Private gstrName As String
[General Code section of Class]
Public Property Let Name(strVal
As String)
gstrName
= strVal
End Property
Public Property Get Name()
As String
Name = gstrName
End Property
> Using a Private Variable of the Class to Store a Property
Notice in Listing 12.2 that you still declare a variable in the class's
General Declarations section as you would when implementing properties with Public variables,
but this time the variable is a Private variable. This means the variable won't be visible
outside the class. You use it to store the value of the property you are implementing, but code
won't access this variable directly. Instead, Property Let and Get procedures will be the
gateway to the property.
> Allowing Writes to a Property with Property Let
The Property Let procedure is a Sub procedure that will run whenever the controlling
code attempts to assign a value to the property, as when, say, it runs code such as:
objMine.Name = "Ciacco"
Notice that the Property Let procedure in Listing 12.2 takes a single parameter.
The parameter holds the value that the controlling code is trying to assign to the property. If
your controlling code had run the single line listed here, the value of the parameter strVal
in the Property Let procedure would be "Ciacco". The Property Let in Listing 12.2 then does what
Property Let procedures almost always do: It stores the incoming parameter value in the Private
variable (gstrName in this case) where the value of the Name property is being held.
> Allowing Reads of a Property with Property Get
Property Get is a Function procedure that will run whenever controlling code attempts
to read the value of the property named by the procedure, as in either of the two lines in
Listing 12.3. Notice that the Property Get in Listing 12.2 takes no parameters, but has a
return type and sets a return value equal to the name of the Property Get procedure, just
as any normal Function procedure does. That is because the Property Get's job is to
pass a value back when controlling code requests it. Typically, the Property Get will do just
as the example in Listing 12.2 does: It will get the value of the property from the value
stored in a Private variable of the class.
LISTING 12.3
CONTROLLER CODE THAT READS THE VALUE OF AN OBJECT'S PROPERTY
ThisName = objMine.Name
MsgBox "And then we met " &
objMine.Name
> Implementing a Read-Only Property
If you would like a property to be read-only for controller code, all you
have to do is leave out the Property Let procedure from your class.
That way, the controller has no way of writing the property. You can still
store the value of the property in a Private variable of the class module. Other parts of
your server class can manipulate the property by changing the Private variable, but the controller
application can't change it directly.
Listing 12.4 implements an Integer-type property to track the number of times the Name
property changes. The tracking property is called Accesses, and is stored in a class Private variable
called giAccesses. The Accesses property would be updated indirectly through giAccesses every
time the Name property gets changed by a controller (the Property Let Name procedure increments
giAccesses). Because there is no written Property Let Accesses procedure, however, there is no
way for controlling code to change the Accesses property directly.
LISTING 12.4
IMPLEMENTING A READ-ONLY CLASS PROPERTY BY OMITTING ITS PROPERTY LET PROCEDURE
[General Declarations of Class]
Private giAccesses As Integer
Private gstrName As String
[Code section of Class]
Property Get Accesses() As
Integer
Accesses
= giAccesses
End Property
Public Property Let Name(strVal As String)
gstrName = strVal
giAccesses = giAccesses +
1
End Property
Public Property Get Name() As String
Name = gstrName
End Property
WARNING - Don't Use Public Variables to Store Intermediate
Property Values: Don't use class Public variables to store Property Let/Get's
intermediate values, because then controller code can read and write them directly,
which will confuse the issue of how to access the property's value. Always use
class Private variables to store the values of properties that you implement with
Property procedures.