Members
Technology Zones
IBM Learning Center
Articles
Hosted By
Info
|
Rated
Read 63,949 times
Contents
Related Categories
Introduction to Class Programming Part II - Advanced Used of Methods
Advanced Used of Methods
In our previous example, our Address property of the Student class is
responsible for proper format of the Student address. For instance, let us pretend that it takes a
lot of processing time to evaluate its result and return the value. If you trace the
execution of the program it executes all the Property Get in order to construct
the correct address format, which we're surely like that the class would do.
But add the Debug.Print statement below:
' Other client form code omitted
' Show Student information in the client form
MsgBox Student.StudentInfo(, True)
' Call the Student StudentAddressInfo method
Debug.Print Student.StudentAddressInfo ' Add this code
|
The code above demonstrate the overhead of calling Student address even if we
don't change address information of the student. In other words, the class
(Address) always evaluate (run) the Property Get even if it is not
necessary to do so because it highly dependent on the independet (such as Street,
City, State, Zip and Country) Property value. So
how can we modify this function to keep the
overhead to a minimum without modifying the interface that the class exposes to
the outside. A common sense solution we case use is don't to reevaluate it
(all independent property, such as Street, City, State, Zip and Country) each time the client code makes a request.
Right! But how? We can store the return value in a Private Variant
variable before returning to the client and reuse that value if possible in all
subsequent calls. The trick works because each time either Street, City,
State,
Zip or Country are assigned a new value, the Private variable is cleared,
which forces it to be reevaluated the next time the CompleteAddress
function is invoked.
' In Address class module declaration
' Other Private member variable omitted
Private m_CompleteAddress As Variant
Public Property Let Street(ByVal strNewStreet As String)
If Len(strNewStreet) = 0 Then Err.Raise 5
m_Street = strNewStreet
m_CompleteAddress = Empty ' add this line in every Property Let Procedures
End Property
' Other Property Let procedure ommited
' Revised CompleteAddress Method
Public Function CompleteAddress() As String
If IsEmpty(m_CompleteAddress) Then
m_CompleteAddress = Street & vbCrLf & City & ", " & _
State & " " & Country & " " & Zip
End If
CompleteAddress = m_CompleteAddress
End Function
|
If trace again the program execution (Pressing F8), the second time you
invoke the CompleteAddress method (via StudentAddressInfo method
of Student class), the class smartly save the previous result and return
it. You might ask "We implement this technique to the Address object,
why we did not implement this to Student class, is it possible?" Yes
of course, but you must understand that a class should be robust, and to
be a robust class, the class should be responsible for himself! As you can
see, even if the CompleteAddress method are highly dependent on
independent properties, it access it dependent property in Address
class in which CompleteAddress is also included. Now lets go back
to the topic, one last note, don't underestimate the advantage of this
technique, because in a real-world application, this difference might involve
unnecessarily opening a database, reestablishing a remote connection, and so on.
Initialization Method
We already explained that the class to be robust, it must always contains a
valid value. And to achieve this objectives, we provide our class a Property
procedures and methods to transform the internal data of the class to
a valid state by providing validation code inside this procedures.
However, if you are familiar with C++ and Java, you might be asking, what if an
object is used immediately after creation of the object or during the creation
of the object in the client side and how can we provide the user or client a
initial valid values? We can provide the client some useful initial valid value
in theClass_Initialize event procedure, without having to specify
it in the client code. Visual Basic offers a neat way by writing some statements
in the Class_Initialize event of the class module. To have the
editor create a template for this event procedure, you select the Class item in
the leftmost combo box in the code editor. Visual Basic automatically selects
the Initialize item from the rightmost combo box control and inserts the
template into the code window.
Because we are dealing with the Student class object, you can provide a
reasonable value for client to expect in its Country property of the Address
object property of the Student. For example, "Philippines" or
whatever nationality appropriate where you live. In this, you would like for
these default values to be assigned when you create an object, rather than,
having assign them manually in the code that uses the class.
' In Address class module
Private Sub Class_Initialize()
m_Country = "Philippines"
End Sub
|
If you trace the program, you will see that as soon as Visual Basic creates
the object (the Set command in the form module), the Class_Initialize
event fires. The object is returned to the caller with all the properties
correctly initialized, and you don't have to assign them in an explicit way.
But this solution might be not enough for us. We just solve the second
problem stated above. What happens if an object is used immediately after its
creation. Consider this example:
' In the Client form
Set Student = New Student
Debug.Print Student.FirstName ' << this will display nothing
Debug.Print Student.FullName ' << this will raise an error
|
In other programming language, this problem is solved by defining a
special procedure that is defined in the class module and executed whenever a
new instance is create, just like C++ and Java constructor. Because Visual
Basic completely lack of constructor method, you can't prevent the user of your
class from using the object as soon as they create it. The best solution
that you can do is create simulated constructor method that correctly initialize
all (if you desire) the properties and let the user know that they can initialize
the object in a short way.
' In the Address class module
Public Sub InitAddress(Optional ByVal Street As Variant, _
Optional ByVal City As Variant, _
Optional ByVal State As Variant, _
Optional ByVal Zip As Variant, _
Optional ByVal Country As Variant)
If Not IsMissing(Street) Then Me.Street = Street
If Not IsMissing(City) Then Me.City = City
If Not IsMissing(State) Then Me.State = State
If Not IsMissing(Zip) Then Me.Zip = Zip
If Not IsMissing(Country) Then Me.Country = Country
End Sub
' In the Student class module
Public Sub InitStudent(Optional ByVal StudentID As Variant, _
Optional ByVal FirstName As Variant, _
Optional ByVal LastName As Variant, _
Optional ByVal Major As MajorCodeEnum = Freshmen, _
Optional ByVal YearLevel As YearLevelEnum = BSCS, _
Optional ByVal BirthDate As Variant, _
Optional ByVal Gender As GenderEnum = Male, _
Optional ByVal Address As Variant, _
Optional ByVal ProvincialAddress As Variant)
If Not IsMissing(StudentID) Then Me.StudentID = StudentID
If Not IsMissing(FirstName) Then Me.FirstName = FirstName
If Not IsMissing(LastName) Then Me.LastName = LastName
If Not IsMissing(Major) Then Me.Major = Major
If Not IsMissing(YearLevel) Then Me.YearLevel = YearLevel
If Not IsMissing(BirthDate) Then Me.BirthDate = BirthDate
If Not IsMissing(Gender) Then Me.Gender = Gender
If Not IsMissing(Address) Then _
Set Me.Address = Address ' Set command is necessary
If Not IsMissing(ProvincialAddress) Then _
Set Me.ProvincialAddress = ProvincialAddress ' also here
End Sub
|
Now you can tell the user of your class, to use your newly created simulated
constructor:
' In the Client form
' Initiate the object Student
Set Student = New Student
Set Address = New Address
Set ProvincialAdd = New Address
' Set up Address
Address.InitAddress "Block 10 Lot 26, Molave Street, Calendola Village", _
"San Pedro", _
"Laguna", _
"4023"
' Set up Provincial address
ProvincialAdd.InitAddress "Block 10 Lot 26, Molave Street, Calendola Village", _
"San Pedro", _
"Laguna", _
"4023"
' Set up Student
Student.InitStudent "12345", "Dante", "Salvador", _
BSCS, Senior, #10/24/1972#, Male, _
Address, ProvincialAdd
' Other code omitted
|
As you can see, we adopt optional arguments of type Variant because it is
essential that you use the IsMissing function and bypass the assignment
of values that were never provided by the client. The good consequence of
this approach is that, we can use default value to the parameter list as shown
in InitStudent method. We also use the same names of the properties they
refer to, this makes the method easier to use and to avoid name conflict inside
the procedure, we use Me keyword to refer to the real properties of the
class.
Now, to add more usability of your class, you can provide a function in a BAS
module in your application that return a newly created object of your class:
' In the Standard module of your application
Public Function New_Student(Optional ByVal StudentID As Variant, _
Optional ByVal FirstName As Variant, _
Optional ByVal LastName As Variant, _
Optional ByVal Major As MajorCodeEnum = Freshmen, _
Optional ByVal YearLevel As YearLevelEnum = BSCS, _
Optional ByVal BirthDate As Variant, _
Optional ByVal Gender As GenderEnum = Male, _
Optional ByVal Address As Variant, _
Optional ByVal ProvincialAddress As Variant) As Student
' Initiate an object Student
Set New_Student = New Student
' Call InitStudent method
New_Student.InitStudent StudentID, FirstName, LastName, MAJOR_CODE_MAX, _
YearLevel, BirthDate, Gender, _
Address, ProvincialAddress
End Function
Public Function New_Address(Optional ByVal Street As Variant, _
Optional ByVal City As Variant, _
Optional ByVal State As Variant, _
Optional ByVal Zip As Variant, _
Optional ByVal Country As Variant) As Address
' Initiate an Address object
Set New_Address = New Address
' Call InitAddress method
New_Address.InitAddress Street, City, State, Zip, Country
End Function
|
See how concise your code in the client form:
' In client form
' Declare Student object
Dim Student As Student
Dim Address As Address
Dim ProvincialAdd As Address
' Initiate and create Address object
Set Address = New_Address("Block 10 Lot 26, Molave Street, " & _
"Calendola Village", _
"San Pedro", _
"Laguna", _
"4023")
' Initiate and create Provincial Address object
Set ProvincialAdd = New_Address("Block 10 Lot 26, Molave Street, " & _
"Calendola Village", _
"San Pedro", _
"Laguna", _
"4023")
' Initiate and create Student object
Set Student = New_Student("12345", "Dante", "Salvador", _
BSCS, Senior, #10/24/1972#, Male, _
Address, ProvincialAdd)
' Show Student information
MsgBox Student.StudentInfo(, True)
|
You can add a little spice to your function, by assigning the Address
property value to the ProvincialAddress property, if the Student
lives in the same address.
' In the Standard module of your application
Public Function New_Student(Optional ByVal StudentID As Variant, _
Optional ByVal FirstName As Variant, _
Optional ByVal LastName As Variant, _
Optional ByVal Major As MajorCodeEnum = Freshmen, _
Optional ByVal YearLevel As YearLevelEnum = BSCS, _
Optional ByVal BirthDate As Variant, _
Optional ByVal Gender As GenderEnum = Male, _
Optional ByVal Address As Variant, _
Optional ByVal ProvincialAddress As Variant) As Student
' Initiate an object Student
Set New_Student = New Student
' Assign the same adddress if ProvincialAddress is not set
If IsMissing(ProvincialAddress) Then Set ProvincialAddress = Address
' Call InitStudent method
New_Student.InitStudent StudentID, FirstName, LastName, MAJOR_CODE_MAX, _
YearLevel, BirthDate, Gender, _
Address, ProvincialAddress
End Function
' In client form
Dim Student As Student
Dim Address As Address
' Initiate and create Address object
Set Address = New_Address("Block 10 Lot 26, Molave Street, " & _
"Calendola Village", _
"San Pedro", _
"Laguna", _
"4023")
' Initiate and create Student object
Set Student = New_Student("12345", "Dante", "Salvador", _
BSCS, Senior, #10/24/1972#, Male, _
Address)
' Show Student information
MsgBox Student.StudentInfo(, True)
' Change the provincial address if you will
With Student
With .ProvincialAddress
.Street = "830 Euclid Avenue"
.City = "Cleveland"
.State = "Ohio"
.Zip = "44114"
.Country = "USA"
End With
End With
' Show Student provincial address info
MsgBox Student.StudentProvincialAddInfo
|
Comments
-
Posted by testorp on 06 Apr 2007
these tutorials are great, have shed a lot of light on a rather difficult subject.
One further expalnation, how can I make the OBJECT an array???
the example givven i... -
Posted by oyejo on 07 Oct 2005
Introduction to Class Programming Part I and II is the best tutorials I ever seen.
I look forward to the next tutorial from this author. :-) -
Posted by bisigreat on 07 Jun 2005
Hi All,
I created a Login form and expect that whenever i load the form the current username on the computer should be displayed on the username textbox. The user can now put his/her password in th... -
Posted by bisigreat on 07 Jun 2005
Over the years, i have been running away from classes because it was ambiguous to me but with what i have read in Class programming Part I, i know it could be fun with OOP. It's was an excellent piece...
I'm not sure what you mean. If you click "Printer Friendly Version", you don't get any adverts or iframes or anything........
|
Search
Related Content
Code Samples
New Members
|