Classes and Collections



In this chapter, we will look first at object oriented programming. Once we get an idea about what is OOP (object oriented programming) then we will build a class and understand how to create and use objects of the class.

Collection is an object that can contain a collection of values. Unlike an array, the values in a collection may be of different types. It is also easy to add an item and delete an item from collection.

Visual Basic doesn't belong to the category of object oriented programming languages. However, Visual Basic is an object-based language.  That means many things in Visual Basic are objects. For instance, the very "form" that you display to interact with user is an object. Each control is an object. And of course we have system objects, such as Printer and Screen. So, Visual Basic has got a lot of objects, but it doesn't yet provide all the features that a true OOPL should provide.

What is Object Oriented Programming?
Our aim is to get an idea about OOP so that we could understand how objects are implemented in Visual Basic.

OOP is a paradigm in which a program is essentially a collection of objects. Each object represents an important entity of the application. For example, in a payroll application an employee is an object. An OOP should support the following features.

Encapsulation
When the data and the code that accesses and manipulates the data are integrated, it is called as Encapsulation. The data of the object forms the attribute of the object. For instance, if object is an employee then employee number is an attribute.  An object may also contain methods - the functions that take actions on the object. For instance, CalcSalary function of  employee object is a method. When you call CalcSalary method, it accesses the data part of the object and calculates salary using the data of the object.

An object contains a set of attributes (called as properties in Visual Basic) and methods. Encapsulation binds the data and code together. 

The advantage with encapsulation is; the data of the object is modified only by the code of the object. The data part of the object is not accessible from outside. It increases programmer's control on the object and as the result on the entire project.

Inheritance
Inheritance provides the crucial advantage of OOP - reusability. Inheritance allows the attributes and methods of an object to be inherited into another object. The object that is inheriting the attributes and methods of another object can further have its own attributes and methods, and can also override methods of the inherited object.

Inheritance allows programmer to use the object that he or someone else has already created and used in old and current projects in new projects. This reduces the time taken for developing new project. Reusability is a very important advantage of OOP. Microsoft's COM (Component Object Model) is based on the principle that once an object is created it can be reused in future. And there is a new paradigm called component software, which deals with creating components that can be reused anywhere. ActiveX controls, Java Beans are example for components.

For example, when you take a circle and an arc, the data of the circle is consisting of coordinates of the center point and the radius. The data of an arc object is containing whatever circle object has plus starting angle and ending angle. If circle is inherited into arc (in other words if arc is derived from circle) we do not have to concentrate on the attributes and methods that will be inherited from circle object, instead we have to concentrate on the new attributes and methods that are to be added to arc object.

Polymorphism
This allows one name to be used for multiple methods. That means you can use same name (Draw) for a method that draws a circle when used with circle and an arc when used with arc object. That means though we use the same name there will be multiple methods (functions). Each method is meant for a different object. This allows programmer to use the same name irrespective of the object. This reduces the number of names the programmer has to remember by providing the same interface (way of doing the job) for different objects. In simple words we use the same interface (name or symbol) though the data on which we perform the operation is different.

What is a Class Module?
Class module in Visual Basic was introduced for the first time in Visual Basic 4.0. Since then it has been widely accepted by Visual Basic programmers. As a matter of fact, class module forms the base for ActiveX servers.   Class module is used to create a class. Once a class is created you can instantiate (create an instance) objects of the class. Class module forms the base for object oriented programming in Visual Basic.

Class, Object, Attribute and Method
In OOP, we deal with classes, objects, attributes and methods. It is important to understand this terminology.

Here is a brief description of all the terms.

Class               is the description of a collection of identical object. Ex: Account.
Object             is an instance of the class. Ex: A single account in a bank.
Attribute         is a data element of the class. Ex: Account number of an account class
Method            is a function that is part of the class. Ex: Deposit of account class

Let us elaborate the discussion of the terms.  Each object is an instance of the class. For example, if an account in a bank is an object then it is an instance or occurrence of a class called "Account". All accounts in the bank are objects of the class account. In the same way if you have an apple and a mango then they are two objects of the class Fruit. So a class describes the attributes and methods that are common to a collection of identical objects. Just like how an account class describes what is common among all accounts in a bank.

Each class describes the attributes and methods. Attributes form the data part of the class. For example, in Account class; account number, current balance, type of account etc. are attributes of the class. Methods are used to take actions. For example, in account class you have Deposit method, which processes deposit of amount into account. In the same way you may have CalcIneterst method, which calculates interest using the data that we have in the class.

That's all. That is what you are expected to understand before you start creating a class using class module.

Creating Account Class
Let us create a class module to create a class called Account. Account class contains the following attributes, methods and events.

Type
Name
Meaning
Properties
Ano
Account number

Ahname
Account holder’s name

Curbal
Current balance

AccountType
Type of the account. Which may be either C – current account, or S-Savings account.
Methods
Init
Initializes the attributes by taking values as parameters.

Deposit
Takes the amount that is being deposited and adds that amount to current balance.

Withdraw
Takes the amount that is being withdrawn as parameter and subtracts the amount from current balance. Checks whether minimum balance is maintained.
Event
InsfficientBalance
This event is fired by Withdraw method when the current balance is not sufficient to process withdrawal.

InvalidAcccountType
This event is fired when AccountType is neither S (Savings) nor C (Current).
Table 24.1: Members of Account class.                     

Curbal and AccountType will be implemented as properties. Curbal is a read-only property.  You can retrieve its value but you cannot change its value. Current balance (Curbal) is changed only though methods.  Ano and Ahname are private, i.e.; they are not accessible from outside the class. They are changed using Init method.

Deposit and Withdraw are two methods that are used to change current balance. When method Withdraw cannot perform the operation because of insufficient balance, it raises the event InsufficientBalance by passing current balance as the parameter of the event. An event is used to pass message to calling unit. Event may be fired to inform the calling unit about  the occurrence of an important event in the object.

AccountType is implemented as a property. It can be accessed from anywhere and it can also be changed from anywhere. So we incorporate code to check whether the new account type is either C or S. If  it is neither S nor C then we raise an event InvalidAccountType.

That is all about the class we want to create. Let us now proceed to create Account class.

Creating a class using class module
To create a class in Visual Basic, you have to create a class module. Each class module is a class in Visual Basic. Variables in class module constitute data of the class and procedures and function constitute code part of the class. Events of the class are used to inform the invoking program about various important events.

Following are the steps to create a class using class module:

1.      Start a new project and select Standard Exe as the type of the project.
2.      Visual Basic creates a new project with a single form (Form1).
3.      Add a new class module to project using Project -> Add Class Module
4.      When you are prompted to select one from the list of class module types, select Class Module and click on Open.
5.      Invoke Properties window of class module and change Name property of the class module to Account.
6.      In General/Declarations of class module declare the following variables.
' Make variable declaration compulsory
Option Explicit

' data part of the class
Private m_ano As Integer
Private m_ahname As String
Private m_curbal As Long
Private m_acctype As String
Listing  24.1: Declaring data members of class module

To create Init method:

1.      When you are in class module Select Tools->Add Procedure.
2.      Enter Init as the name of the procedure and click on Ok button.
3.      Enter the following code for procedure.

Public Sub Init(ano As Integer, ahname As String, curbal As Long, acctype As String)

  'assign the values passed as parameters to variable of
  'the class
  m_ano = ano
  m_ahname = ahname
  m_curbal = curbal
  m_acctype = acctype
End Sub
Listing 24.2: Init procedure of Account class.

Method Init is used to take values for four attributes of the class and assign those values to corresponding attributes. Note that each attribute is represented by a private variable. All these private variables are accessible only within the class. They are accessed only through methods (procedures and functions) of the class. In this case, Init method is used to set attributes of the class to the required values.

To create Deposit method:

1.      Select Tools->Add Procedure being in class module.
2.      Enter Deposit as the name of the procedure and click on Ok.
3.      Enter the following code.
Public Sub Deposit(amt As Long)
     ' add amount to current balance
      m_curbal = m_curbal + amt
End Sub
Listing 24.3: Deposit method of Account class.

Creating Properties for Account class
So far we have created two methods of Account class - Init and Deposit. Now let us concentrate on creating properties for Account class.

A property of the class is a name that represents an attribute of the class. But there is difference between exposing a variable by making a variable of the class public variable and creating a property to represent the attribute. When you make a variable public, it can be accessed from outside the class and manipulated and the class has no control on the value that is being stored in the variable. For example, first  m_AccType is made public then, the code that is using m_AccType variable of the class can set it to any character. But the character stored in m_AccType should be either C or S and this condition cannot be checked if you are using a public variable. So we need a property for that and that property is used to access a variable of the class

When you represent an attribute using a property, the following happens:

¨         Property is used to access the variable indirectly.
¨         Whenever you store a value into property, Property Let procedure is invoked and that is used to store the value in the corresponding variable of the class.
¨         Whenever you retrieve the value of the property, Property Get procedure is invoked and that is used to return the value of the corresponding variable of the class.

So creating a property gives programmer a chance to check whether the value that is being stored is valid or not.

Creating AccountType property
Property AccountType is used to access and change the type of the account. In other words, it represents the m_AccType variable of the class. By hiding m_AccType variable and accessing  AccountType propety, we gain control on the value that is being stored in m_AccType.

Here is the complete process related to creating AccountType property.

¨         We create a property called AccountType.
¨         Visual Basic creates two procedures: one is Property Let procedure and another one is Property Get procedure.
¨         Property Let procedure is invoked whenever AccountType property is assigned a value. It has parameter that contains the value being passed. We check whether this is a valid value. If it is valid we assign this value to m_AccType variable of the class, otherwise we raise InvalidAccountType event.
¨         Property Get function is invoked whenever the value of AccountType is taken. It returns the value of m_AccType as the return value. Whatever value you return from Property Get procedure that will be the value of the AccountType property.

Now let us create AccountType property for Account class.

To create AccountType property:

1.      Select Tools -> Add Procedure being in Class module.
2.      Enter AccountType as the name of the procedure and select Property radio button in Type group.
3.      Visual Basic create two new procedures as follows:

Public Property Get AcountType() As Variant

End Property

Public Property Let AcountType(ByVal vNewValue As Variant)

End Property

In Property Let procedure the parameter vNewValue contains the value that is assigned to property by the invoking code. If value ‘S’ is assigned to AccountType then vNewValue contains ‘S’

Let us write code for each of the procedure as follows.

Public Property Get AcountType() As String
    ' return the value of m_acctype
    AccountType = m_acctype
End Property

Public Property Let AcountType(ByVal NewAccType As String)
  ' check whether value is valid
  If NewAccType = "S" Or NewAccType = "C" Then
       m_acctype = NewAccType
  Else
       ' raise event that is handled by calling module
       RaiseEvent InvalidAccountType
  End If
End Property
Listing 24.4: Code for AccountType property.

InvalidAccountType (that will be created later) is an event of Account class that is used to notify the calling module that an error has occurred while changing AccountType property. We also need one more event called InsufficientBalance, which is called from WithDraw method.

Creating Events
Creating events in the class module is done as follows:

1.      Select Tools-> Add Procedure being in Class module.
2.      Enter InvalidAccountType as the name of the event and select Event radio button in Type group.
3.      Visual Basic places a single statement in General/Declarations section as shown in listing 24.5.
4.      Repeat steps 1 to 3 and create InsufficientBalance event.
5.      InsufficientBalance event has a parameter of Long type. So add that parameter to that event. See listing 24.5 for details.
Public Event InvalidAccountType()

Public Event InsufficientBalance(Amt As Long)
Listing 24.5: Events of the Account class.

RaiseEvent statement
RaiseEvent is used to fire events that are declared at module level of a class module.

RaiseEvent eventname [(argumentlist)]

Eventname is the name of the event that is to be raised.

Argumentlist is the list of argument that you want to pass to event. It is optional. It is used only when you have arguments for event.

Adding Withdraw method
Withdraw method takes the amount to be withdrawn and subtracts that amount from current balance. But if current balance is not sufficient then it raises InsufficientBalance event by passing the available current balance.

While checking whether balance is sufficient or not it takes minimum value into account. The minimum value is 500 for Savings account and 1000 for current account.

To create withdraw method:

1.      Select Tools->Add Procedure being in Class module.
2.      Enter WithDraw as the name of the procedure.
3.      Enter the following code.
Public Sub WithDraw(amt As Long)
Dim mbal As Integer

  ' find out minimum balance
  If m_acctype = "C" Then
     mbal = 1000
  Else
     mbal = 500
  End If
 
  ' check whether amount is sufficient
  If m_curbal - mbal >= amt Then    ' balance is sufficient
      m_curbal = m_curbal - amt
  Else
      ' raise event and pass m_curbal as parameter
      RaiseEvent InsufficientBalance(m_curbal)
 End If
End Sub
Listing 24.6: Code for Withdraw method.

Creating CurBal property
The last step is creating CurBal property. The special thing about this property is, it is read-only property.

The process is same as creating AccountType property. But as CurBal is a read-only property. So it cannot be modified, it can only return the current balance. That means it has only property get procedure and no property let procedure.

Note: A function that returns the current balance serves the same purpose as a read-only property, CurBal.

To create CurBal as a read-only property:

1.      Select Tools->Add Procedure being in class module
2.      Enter CurBal as the name and select Property radio button in Type group.
3.      Click on Ok button
Visual Basic creates two procedures, one is Property Let and another one is Property Get.
4.      Delete Property Let procedure from the class by selecting it in code window and then pressing delete key.

Public Property Get CurBal() As Long
     ' return current balance
     CurBal = m_curbal
End Property
Listing 24.7: CurBal property get procedure.

The following is the complete code of the Account class module.

General/Declarations
Option Explicit

' data part of the class
Private m_ano As Integer
Private m_ahname As String
Private m_curbal As Long
Private m_acctype As String

Public Event InvalidAccountType()

Public Event InsufficientBalance(amt As Long)

Public Sub Init(ano As Integer, ahname As String, CurBal As Long, acctype As String)

  'assign the values passed as parameters to variable of the class
  m_ano = ano
  m_ahname = ahname
  m_curbal = CurBal
  m_acctype = acctype
End Sub

Public Sub Deposit(amt As Long)
     ' add amount to current balance
      m_curbal = m_curbal + amt
End Sub

Public Property Get AcountType() As String
    ' return the value of m_acctype
    AccountType = m_acctype
End Property

Public Property Let AcountType(ByVal NewAccType As String)
  ' check whether value is valid
  If NewAccType = "S" Or NewAccType = "C" Then
       m_acctype = NewAccType
  Else
       RaiseEvent InvalidAccountType
  End If
 
End Property

Public Sub WithDraw(amt As Long)

Dim mbal As Integer

  ' find out minimum balance
  If m_acctype = "C" Then
     mbal = 1000
  Else
     mbal = 500
  End If
 
  ' check whether amount is sufficient
  If m_curbal - mbal >= amt Then    ' balance is sufficient
      m_curbal = m_curbal - amt
  Else
      ' raise event and pass m_curbal as parameter
      RaiseEvent InsufficientBalance(m_curbal)
  End If
End Sub

Public Property Get CurBal() As Long
     ' return current balance
     CurBal = m_curbal
End Property
Listing 24.8: Complete code for Account class.

Using Account Class
We have so far concentrated on creating Account class. Let us now see how we can use Account class. We will develop a simple form  to demonstrate how to use Account class.
Start a new Standard Exe project and write the following code in General/Declarations section of the Form1.

Option Explicit
Dim WithEvents acc As Account

Listing 24.9: Declaring an object of Account class.

Option Explicit is to make variable declaration mandatory.

Acc is an object of Account class.  That means Acc is an instance of the class Account. To use any class you must first declare objects for the class.

WithEvents keyword specifies that there are events associated with the objects. Only when WithEvents keyword is used at the time of declaring object you will be able to handle events that are raised by the object. When you declare an object with WithEvents option, Visual Basic includes the object as one of the objects in Code window. For instance now if you invoke code window and open the drop down list of objects on the left, you find acc as one of the objects (see figure 24.2).

An object is to be declared and then defined (created).

At the time of declaration, you specify the name of the object and the class to which the object belongs. To declare the object use the following format:

Dim object as class

Here, object is the name of the object and class is the name of the class.

After the object is declared it is to be created using New keyword. When object is created, memory is allocated to object and the Initialize event of the class is fired.

In our example application, use Load event of the form to create a new object and initialize its attributes using Init method of the class. Code is shown in listing 24.10 .

Private Sub Form_Load()
 'create new object of Account type
 Set acc = New Account
 'initialize data of the object
 acc.Init 1, "Srikanth", 20000, "C"
End Sub
Listing 24.10: Code to initialize account object - acc.

Add three command buttons to form to use methods and properties of the Account class. Change the properties of the command buttons as follows.

Control
Property
Value
Command1
Name
CmdDeposit

Caption
&Deposit
Command2
Name
CmdWithdraw

Caption
&WithDraw
Command3
Name
Cmdchangetype

Caption
&Change Account Type

Write the following code for three command buttons.

Private Sub cmdChangeType_Click()
Dim atype As String

 'Accept new account type
 atype = InputBox("Enter new account type", "Account Type")
 acc.AcountType = atype

End Sub

Private Sub cmdDeposit_Click()
Dim amt As Long
 ' take amount being deposited
 amt = InputBox("Enter deposit amount", "Deposit")
 acc.Deposit amt
 ' display new current balance
 MsgBox "Current Balance" & Str(acc.CurBal), , "Balance"

End Sub

Private Sub cmdwithdraw_Click()
Dim amt As Long
Dim pcurbal As Long
 'take amount being withdrawn
 amt = InputBox("Enter amount to withdraw", "WithDraw")
 'remember current balance before withdrawl
 pcurbal = acc.CurBal
 acc.WithDraw amt
 If acc.CurBal <> pcurbal Then
     'display new current balance
     MsgBox "Current Balance" & Str(acc.CurBal), , "Balance"
 End If
End Sub
Listing 24.11: Code for command buttons in the form.

For Withdraw and Change Account Type, there is a chance of making a mistake. For example, the current balance may not be sufficient to execute withdrawal. In the same way, the character entered for account type may not be “S” or “C”. In these cases class raises events. We have to handle those events in form module. Here is the code to handle events.

Private Sub acc_InsufficientBalance(amt As Long)
  MsgBox "Insufficient Balance to perform the requested operation", , "Error"
End Sub

Private Sub acc_InvalidAccountType()
  MsgBox "The value entered for Account type should be either S-Savings or C-current", , "Error"
End Sub
Listing 24.12: Code for events of the class object.

Well, Now you know how to create a class and use it in a form. The process is the same no matter how complex and how big a class is. You just have to concentrate on properties (Attributes), methods and events. 

Note: The properties, methods and events of a class are called as the interface of the class.

Using a Collection
A collection is a collection of items, where items may be of different types.  The item may be an object of class or any standard data type. To understand how to use collections, let us use create a sample application. The sample application creates a class to contain a collection of objects of Account class

To create sample application:

1.      Start a new project using File-> New project and select Standard Exe as the type of the project.
2.      And place controls as shown in figure 23.4.
3.      Change the following properties of the controls.
Control
Property
Value
Frame1
Caption
Account Details
Label1
Caption
Ano

Autosize
True
Label2
Caption
Name

Autosize
True
Label3
Caption
Balance

Autosize
True
Label4
Caption
Type

Autosize
True
Text1
Name
Txtano

Text
""
Text2
Name
Txtahname

Text
""
Text3
Name
Txtcb

Text
""
Text1
Name
TxtType

Text
""
Command1
Name
CmdAdd

Caption
&Add
Command2
Name
CmdDelete

Caption
&Delete
Command3
Name
CmdSearch

Caption
&Search
Command4
Name
CmdList

Caption
&List
Command5
Name
Cmdquit

Caption
&Quit
List1
Name
LstAccounts
Form1
Caption
Collections's Demo

4.      Declare a collection object in General/Declarations as follows.

Dim Accounts As New Collection

Write code for Add command button. When user clicks on Add button after entering data into text boxes, create an object of Account class and put data entered by user into that object and then add that object to collection using Add method.  Account Number (Ano) will be the key for the item added to collection. Key of the item may be used to retrieve the item from the collection.

You can access an item of collection either by using index of the item or by using Key of the item. The key is specified at the time of adding an item as the second parameter for Add method of the collection. The key must be string type.

The syntax of Add method is:

Add item, key, before, after

The meaning of each parameter is as follows.

Parameter
Meaning
Item
The item to be added to the collection.
Key
The key of the item that is being added to the collection. The key should be a string.
Before
Specifies that the new item should be added to the collection before the specified item. Item is identified either by key or by index.
After
Specifies that the new item should be added to the collection after the specified item. Item is identified either by key or by index.





Note: If before and after are not given in Add method, the new item is added to the end of the collection.

Here is the complete code to add an account object to the collection.

Private Sub cmdAdd_Click()
 Dim acc As New Account
 ' place data into object
 acc.Init CInt(txtAno.Text), txtAhname.Text, txtCb.Text, txtType.Text
 'add object to collection with ANO as the key
 Accounts.Add acc, txtAno.Text
 ClearFields
End Sub
Listing 24.13: Code for Add button.

The code for ClearFields, which is used to empty text boxes in procedure is as follows:
Public Sub ClearFields()
   ' empty all text boxes
   txtAno.Text = ""
   txtAhname.Text = ""
   txtCb.Text = ""
   txtType.Text = ""
End Sub
Listing 24.14: Code for ClearFields procedure.

To list out the item in the collection, enter the following code for Click event of cmdList command button.
Private Sub cmdlist_Click()
Dim acc As Account
  ' clear all values from listbox
  lstAccounts.Clear
  ' populate listbox using values in the collection
  For Each acc In Accounts
     'concatenate all the values
     With acc
        gap = Space(5)
        st = Str(.Ano) & gap & .Ahname & gap
        st = st & Str(.CurBal) & gap & .AccountType
        lstAccounts.AddItem st
     End With
  Next
End Sub
Listing 24.15: Code for List command button.

Note: For Each ... loop is a special loop designed specifically for collections. For more details see chapter 17.

To delete an item, whose account number is entered in txtAno text box, enter the following code for cmdDelete command button.

Private Sub cmdDelete_Click()
 On Error GoTo errlbl
 ' delete the details of the account whose ANO is entered
 ' in txtAno textbox
 Accounts.Remove txtAno.Text
 Exit Sub
errlbl:
 MsgBox "Account Number is not Found"
End Sub
Listing 24:16: Code for Delete command button.

Remove method of the collection takes a single parameter, which is either index of the item to be removed or the key of the item. If it is a string, it is treated as the key. If it is of numeric type, it is treated as index of the item to be removed.

If the given key or index is not found in the collection, a runtime error occurs. So trap the error and display error message.

To get the details of an account, whose account number is entered in txtano text box, enter the following code:

Private Sub cmdSearch_Click()
Dim acc As Account
  On Error GoTo errlbl
  ' get details of the account whose ano is entered
  ' in txtAno textbox
  Set acc = Accounts.Item(txtAno.Text)
  With acc
     txtAno.Text = .Ano
     txtAhname.Text = .Ahname
     txtCb.Text = .CurBal
     txtType.Text = .AccountType
  End With
  Exit Sub
errlbl:
    MsgBox "Account Number not found"
End Sub
Listing 24:17: Code for Search button.

Item method results in runtime error if the given index is not found in the collection. So handle the runtime error and display a message to user.

No comments:

Classes and Collections



In this chapter, we will look first at object oriented programming. Once we get an idea about what is OOP (object oriented programming) then we will build a class and understand how to create and use objects of the class.

Collection is an object that can contain a collection of values. Unlike an array, the values in a collection may be of different types. It is also easy to add an item and delete an item from collection.

Visual Basic doesn't belong to the category of object oriented programming languages. However, Visual Basic is an object-based language.  That means many things in Visual Basic are objects. For instance, the very "form" that you display to interact with user is an object. Each control is an object. And of course we have system objects, such as Printer and Screen. So, Visual Basic has got a lot of objects, but it doesn't yet provide all the features that a true OOPL should provide.

What is Object Oriented Programming?
Our aim is to get an idea about OOP so that we could understand how objects are implemented in Visual Basic.

OOP is a paradigm in which a program is essentially a collection of objects. Each object represents an important entity of the application. For example, in a payroll application an employee is an object. An OOP should support the following features.

Encapsulation
When the data and the code that accesses and manipulates the data are integrated, it is called as Encapsulation. The data of the object forms the attribute of the object. For instance, if object is an employee then employee number is an attribute.  An object may also contain methods - the functions that take actions on the object. For instance, CalcSalary function of  employee object is a method. When you call CalcSalary method, it accesses the data part of the object and calculates salary using the data of the object.

An object contains a set of attributes (called as properties in Visual Basic) and methods. Encapsulation binds the data and code together. 

The advantage with encapsulation is; the data of the object is modified only by the code of the object. The data part of the object is not accessible from outside. It increases programmer's control on the object and as the result on the entire project.

Inheritance
Inheritance provides the crucial advantage of OOP - reusability. Inheritance allows the attributes and methods of an object to be inherited into another object. The object that is inheriting the attributes and methods of another object can further have its own attributes and methods, and can also override methods of the inherited object.

Inheritance allows programmer to use the object that he or someone else has already created and used in old and current projects in new projects. This reduces the time taken for developing new project. Reusability is a very important advantage of OOP. Microsoft's COM (Component Object Model) is based on the principle that once an object is created it can be reused in future. And there is a new paradigm called component software, which deals with creating components that can be reused anywhere. ActiveX controls, Java Beans are example for components.

For example, when you take a circle and an arc, the data of the circle is consisting of coordinates of the center point and the radius. The data of an arc object is containing whatever circle object has plus starting angle and ending angle. If circle is inherited into arc (in other words if arc is derived from circle) we do not have to concentrate on the attributes and methods that will be inherited from circle object, instead we have to concentrate on the new attributes and methods that are to be added to arc object.

Polymorphism
This allows one name to be used for multiple methods. That means you can use same name (Draw) for a method that draws a circle when used with circle and an arc when used with arc object. That means though we use the same name there will be multiple methods (functions). Each method is meant for a different object. This allows programmer to use the same name irrespective of the object. This reduces the number of names the programmer has to remember by providing the same interface (way of doing the job) for different objects. In simple words we use the same interface (name or symbol) though the data on which we perform the operation is different.

What is a Class Module?
Class module in Visual Basic was introduced for the first time in Visual Basic 4.0. Since then it has been widely accepted by Visual Basic programmers. As a matter of fact, class module forms the base for ActiveX servers.   Class module is used to create a class. Once a class is created you can instantiate (create an instance) objects of the class. Class module forms the base for object oriented programming in Visual Basic.

Class, Object, Attribute and Method
In OOP, we deal with classes, objects, attributes and methods. It is important to understand this terminology.

Here is a brief description of all the terms.

Class               is the description of a collection of identical object. Ex: Account.
Object             is an instance of the class. Ex: A single account in a bank.
Attribute         is a data element of the class. Ex: Account number of an account class
Method            is a function that is part of the class. Ex: Deposit of account class

Let us elaborate the discussion of the terms.  Each object is an instance of the class. For example, if an account in a bank is an object then it is an instance or occurrence of a class called "Account". All accounts in the bank are objects of the class account. In the same way if you have an apple and a mango then they are two objects of the class Fruit. So a class describes the attributes and methods that are common to a collection of identical objects. Just like how an account class describes what is common among all accounts in a bank.

Each class describes the attributes and methods. Attributes form the data part of the class. For example, in Account class; account number, current balance, type of account etc. are attributes of the class. Methods are used to take actions. For example, in account class you have Deposit method, which processes deposit of amount into account. In the same way you may have CalcIneterst method, which calculates interest using the data that we have in the class.

That's all. That is what you are expected to understand before you start creating a class using class module.

Creating Account Class
Let us create a class module to create a class called Account. Account class contains the following attributes, methods and events.

Type
Name
Meaning
Properties
Ano
Account number

Ahname
Account holder’s name

Curbal
Current balance

AccountType
Type of the account. Which may be either C – current account, or S-Savings account.
Methods
Init
Initializes the attributes by taking values as parameters.

Deposit
Takes the amount that is being deposited and adds that amount to current balance.

Withdraw
Takes the amount that is being withdrawn as parameter and subtracts the amount from current balance. Checks whether minimum balance is maintained.
Event
InsfficientBalance
This event is fired by Withdraw method when the current balance is not sufficient to process withdrawal.

InvalidAcccountType
This event is fired when AccountType is neither S (Savings) nor C (Current).
Table 24.1: Members of Account class.                     

Curbal and AccountType will be implemented as properties. Curbal is a read-only property.  You can retrieve its value but you cannot change its value. Current balance (Curbal) is changed only though methods.  Ano and Ahname are private, i.e.; they are not accessible from outside the class. They are changed using Init method.

Deposit and Withdraw are two methods that are used to change current balance. When method Withdraw cannot perform the operation because of insufficient balance, it raises the event InsufficientBalance by passing current balance as the parameter of the event. An event is used to pass message to calling unit. Event may be fired to inform the calling unit about  the occurrence of an important event in the object.

AccountType is implemented as a property. It can be accessed from anywhere and it can also be changed from anywhere. So we incorporate code to check whether the new account type is either C or S. If  it is neither S nor C then we raise an event InvalidAccountType.

That is all about the class we want to create. Let us now proceed to create Account class.

Creating a class using class module
To create a class in Visual Basic, you have to create a class module. Each class module is a class in Visual Basic. Variables in class module constitute data of the class and procedures and function constitute code part of the class. Events of the class are used to inform the invoking program about various important events.

Following are the steps to create a class using class module:

1.      Start a new project and select Standard Exe as the type of the project.
2.      Visual Basic creates a new project with a single form (Form1).
3.      Add a new class module to project using Project -> Add Class Module
4.      When you are prompted to select one from the list of class module types, select Class Module and click on Open.
5.      Invoke Properties window of class module and change Name property of the class module to Account.
6.      In General/Declarations of class module declare the following variables.
' Make variable declaration compulsory
Option Explicit

' data part of the class
Private m_ano As Integer
Private m_ahname As String
Private m_curbal As Long
Private m_acctype As String
Listing  24.1: Declaring data members of class module

To create Init method:

1.      When you are in class module Select Tools->Add Procedure.
2.      Enter Init as the name of the procedure and click on Ok button.
3.      Enter the following code for procedure.

Public Sub Init(ano As Integer, ahname As String, curbal As Long, acctype As String)

  'assign the values passed as parameters to variable of
  'the class
  m_ano = ano
  m_ahname = ahname
  m_curbal = curbal
  m_acctype = acctype
End Sub
Listing 24.2: Init procedure of Account class.

Method Init is used to take values for four attributes of the class and assign those values to corresponding attributes. Note that each attribute is represented by a private variable. All these private variables are accessible only within the class. They are accessed only through methods (procedures and functions) of the class. In this case, Init method is used to set attributes of the class to the required values.

To create Deposit method:

1.      Select Tools->Add Procedure being in class module.
2.      Enter Deposit as the name of the procedure and click on Ok.
3.      Enter the following code.
Public Sub Deposit(amt As Long)
     ' add amount to current balance
      m_curbal = m_curbal + amt
End Sub
Listing 24.3: Deposit method of Account class.

Creating Properties for Account class
So far we have created two methods of Account class - Init and Deposit. Now let us concentrate on creating properties for Account class.

A property of the class is a name that represents an attribute of the class. But there is difference between exposing a variable by making a variable of the class public variable and creating a property to represent the attribute. When you make a variable public, it can be accessed from outside the class and manipulated and the class has no control on the value that is being stored in the variable. For example, first  m_AccType is made public then, the code that is using m_AccType variable of the class can set it to any character. But the character stored in m_AccType should be either C or S and this condition cannot be checked if you are using a public variable. So we need a property for that and that property is used to access a variable of the class

When you represent an attribute using a property, the following happens:

¨         Property is used to access the variable indirectly.
¨         Whenever you store a value into property, Property Let procedure is invoked and that is used to store the value in the corresponding variable of the class.
¨         Whenever you retrieve the value of the property, Property Get procedure is invoked and that is used to return the value of the corresponding variable of the class.

So creating a property gives programmer a chance to check whether the value that is being stored is valid or not.

Creating AccountType property
Property AccountType is used to access and change the type of the account. In other words, it represents the m_AccType variable of the class. By hiding m_AccType variable and accessing  AccountType propety, we gain control on the value that is being stored in m_AccType.

Here is the complete process related to creating AccountType property.

¨         We create a property called AccountType.
¨         Visual Basic creates two procedures: one is Property Let procedure and another one is Property Get procedure.
¨         Property Let procedure is invoked whenever AccountType property is assigned a value. It has parameter that contains the value being passed. We check whether this is a valid value. If it is valid we assign this value to m_AccType variable of the class, otherwise we raise InvalidAccountType event.
¨         Property Get function is invoked whenever the value of AccountType is taken. It returns the value of m_AccType as the return value. Whatever value you return from Property Get procedure that will be the value of the AccountType property.

Now let us create AccountType property for Account class.

To create AccountType property:

1.      Select Tools -> Add Procedure being in Class module.
2.      Enter AccountType as the name of the procedure and select Property radio button in Type group.
3.      Visual Basic create two new procedures as follows:

Public Property Get AcountType() As Variant

End Property

Public Property Let AcountType(ByVal vNewValue As Variant)

End Property

In Property Let procedure the parameter vNewValue contains the value that is assigned to property by the invoking code. If value ‘S’ is assigned to AccountType then vNewValue contains ‘S’

Let us write code for each of the procedure as follows.

Public Property Get AcountType() As String
    ' return the value of m_acctype
    AccountType = m_acctype
End Property

Public Property Let AcountType(ByVal NewAccType As String)
  ' check whether value is valid
  If NewAccType = "S" Or NewAccType = "C" Then
       m_acctype = NewAccType
  Else
       ' raise event that is handled by calling module
       RaiseEvent InvalidAccountType
  End If
End Property
Listing 24.4: Code for AccountType property.

InvalidAccountType (that will be created later) is an event of Account class that is used to notify the calling module that an error has occurred while changing AccountType property. We also need one more event called InsufficientBalance, which is called from WithDraw method.

Creating Events
Creating events in the class module is done as follows:

1.      Select Tools-> Add Procedure being in Class module.
2.      Enter InvalidAccountType as the name of the event and select Event radio button in Type group.
3.      Visual Basic places a single statement in General/Declarations section as shown in listing 24.5.
4.      Repeat steps 1 to 3 and create InsufficientBalance event.
5.      InsufficientBalance event has a parameter of Long type. So add that parameter to that event. See listing 24.5 for details.
Public Event InvalidAccountType()

Public Event InsufficientBalance(Amt As Long)
Listing 24.5: Events of the Account class.

RaiseEvent statement
RaiseEvent is used to fire events that are declared at module level of a class module.

RaiseEvent eventname [(argumentlist)]

Eventname is the name of the event that is to be raised.

Argumentlist is the list of argument that you want to pass to event. It is optional. It is used only when you have arguments for event.

Adding Withdraw method
Withdraw method takes the amount to be withdrawn and subtracts that amount from current balance. But if current balance is not sufficient then it raises InsufficientBalance event by passing the available current balance.

While checking whether balance is sufficient or not it takes minimum value into account. The minimum value is 500 for Savings account and 1000 for current account.

To create withdraw method:

1.      Select Tools->Add Procedure being in Class module.
2.      Enter WithDraw as the name of the procedure.
3.      Enter the following code.
Public Sub WithDraw(amt As Long)
Dim mbal As Integer

  ' find out minimum balance
  If m_acctype = "C" Then
     mbal = 1000
  Else
     mbal = 500
  End If
 
  ' check whether amount is sufficient
  If m_curbal - mbal >= amt Then    ' balance is sufficient
      m_curbal = m_curbal - amt
  Else
      ' raise event and pass m_curbal as parameter
      RaiseEvent InsufficientBalance(m_curbal)
 End If
End Sub
Listing 24.6: Code for Withdraw method.

Creating CurBal property
The last step is creating CurBal property. The special thing about this property is, it is read-only property.

The process is same as creating AccountType property. But as CurBal is a read-only property. So it cannot be modified, it can only return the current balance. That means it has only property get procedure and no property let procedure.

Note: A function that returns the current balance serves the same purpose as a read-only property, CurBal.

To create CurBal as a read-only property:

1.      Select Tools->Add Procedure being in class module
2.      Enter CurBal as the name and select Property radio button in Type group.
3.      Click on Ok button
Visual Basic creates two procedures, one is Property Let and another one is Property Get.
4.      Delete Property Let procedure from the class by selecting it in code window and then pressing delete key.

Public Property Get CurBal() As Long
     ' return current balance
     CurBal = m_curbal
End Property
Listing 24.7: CurBal property get procedure.

The following is the complete code of the Account class module.

General/Declarations
Option Explicit

' data part of the class
Private m_ano As Integer
Private m_ahname As String
Private m_curbal As Long
Private m_acctype As String

Public Event InvalidAccountType()

Public Event InsufficientBalance(amt As Long)

Public Sub Init(ano As Integer, ahname As String, CurBal As Long, acctype As String)

  'assign the values passed as parameters to variable of the class
  m_ano = ano
  m_ahname = ahname
  m_curbal = CurBal
  m_acctype = acctype
End Sub

Public Sub Deposit(amt As Long)
     ' add amount to current balance
      m_curbal = m_curbal + amt
End Sub

Public Property Get AcountType() As String
    ' return the value of m_acctype
    AccountType = m_acctype
End Property

Public Property Let AcountType(ByVal NewAccType As String)
  ' check whether value is valid
  If NewAccType = "S" Or NewAccType = "C" Then
       m_acctype = NewAccType
  Else
       RaiseEvent InvalidAccountType
  End If
 
End Property

Public Sub WithDraw(amt As Long)

Dim mbal As Integer

  ' find out minimum balance
  If m_acctype = "C" Then
     mbal = 1000
  Else
     mbal = 500
  End If
 
  ' check whether amount is sufficient
  If m_curbal - mbal >= amt Then    ' balance is sufficient
      m_curbal = m_curbal - amt
  Else
      ' raise event and pass m_curbal as parameter
      RaiseEvent InsufficientBalance(m_curbal)
  End If
End Sub

Public Property Get CurBal() As Long
     ' return current balance
     CurBal = m_curbal
End Property
Listing 24.8: Complete code for Account class.

Using Account Class
We have so far concentrated on creating Account class. Let us now see how we can use Account class. We will develop a simple form  to demonstrate how to use Account class.
Start a new Standard Exe project and write the following code in General/Declarations section of the Form1.

Option Explicit
Dim WithEvents acc As Account

Listing 24.9: Declaring an object of Account class.

Option Explicit is to make variable declaration mandatory.

Acc is an object of Account class.  That means Acc is an instance of the class Account. To use any class you must first declare objects for the class.

WithEvents keyword specifies that there are events associated with the objects. Only when WithEvents keyword is used at the time of declaring object you will be able to handle events that are raised by the object. When you declare an object with WithEvents option, Visual Basic includes the object as one of the objects in Code window. For instance now if you invoke code window and open the drop down list of objects on the left, you find acc as one of the objects (see figure 24.2).

An object is to be declared and then defined (created).

At the time of declaration, you specify the name of the object and the class to which the object belongs. To declare the object use the following format:

Dim object as class

Here, object is the name of the object and class is the name of the class.

After the object is declared it is to be created using New keyword. When object is created, memory is allocated to object and the Initialize event of the class is fired.

In our example application, use Load event of the form to create a new object and initialize its attributes using Init method of the class. Code is shown in listing 24.10 .

Private Sub Form_Load()
 'create new object of Account type
 Set acc = New Account
 'initialize data of the object
 acc.Init 1, "Srikanth", 20000, "C"
End Sub
Listing 24.10: Code to initialize account object - acc.

Add three command buttons to form to use methods and properties of the Account class. Change the properties of the command buttons as follows.

Control
Property
Value
Command1
Name
CmdDeposit

Caption
&Deposit
Command2
Name
CmdWithdraw

Caption
&WithDraw
Command3
Name
Cmdchangetype

Caption
&Change Account Type

Write the following code for three command buttons.

Private Sub cmdChangeType_Click()
Dim atype As String

 'Accept new account type
 atype = InputBox("Enter new account type", "Account Type")
 acc.AcountType = atype

End Sub

Private Sub cmdDeposit_Click()
Dim amt As Long
 ' take amount being deposited
 amt = InputBox("Enter deposit amount", "Deposit")
 acc.Deposit amt
 ' display new current balance
 MsgBox "Current Balance" & Str(acc.CurBal), , "Balance"

End Sub

Private Sub cmdwithdraw_Click()
Dim amt As Long
Dim pcurbal As Long
 'take amount being withdrawn
 amt = InputBox("Enter amount to withdraw", "WithDraw")
 'remember current balance before withdrawl
 pcurbal = acc.CurBal
 acc.WithDraw amt
 If acc.CurBal <> pcurbal Then
     'display new current balance
     MsgBox "Current Balance" & Str(acc.CurBal), , "Balance"
 End If
End Sub
Listing 24.11: Code for command buttons in the form.

For Withdraw and Change Account Type, there is a chance of making a mistake. For example, the current balance may not be sufficient to execute withdrawal. In the same way, the character entered for account type may not be “S” or “C”. In these cases class raises events. We have to handle those events in form module. Here is the code to handle events.

Private Sub acc_InsufficientBalance(amt As Long)
  MsgBox "Insufficient Balance to perform the requested operation", , "Error"
End Sub

Private Sub acc_InvalidAccountType()
  MsgBox "The value entered for Account type should be either S-Savings or C-current", , "Error"
End Sub
Listing 24.12: Code for events of the class object.

Well, Now you know how to create a class and use it in a form. The process is the same no matter how complex and how big a class is. You just have to concentrate on properties (Attributes), methods and events. 

Note: The properties, methods and events of a class are called as the interface of the class.

Using a Collection
A collection is a collection of items, where items may be of different types.  The item may be an object of class or any standard data type. To understand how to use collections, let us use create a sample application. The sample application creates a class to contain a collection of objects of Account class

To create sample application:

1.      Start a new project using File-> New project and select Standard Exe as the type of the project.
2.      And place controls as shown in figure 23.4.
3.      Change the following properties of the controls.
Control
Property
Value
Frame1
Caption
Account Details
Label1
Caption
Ano

Autosize
True
Label2
Caption
Name

Autosize
True
Label3
Caption
Balance

Autosize
True
Label4
Caption
Type

Autosize
True
Text1
Name
Txtano

Text
""
Text2
Name
Txtahname

Text
""
Text3
Name
Txtcb

Text
""
Text1
Name
TxtType

Text
""
Command1
Name
CmdAdd

Caption
&Add
Command2
Name
CmdDelete

Caption
&Delete
Command3
Name
CmdSearch

Caption
&Search
Command4
Name
CmdList

Caption
&List
Command5
Name
Cmdquit

Caption
&Quit
List1
Name
LstAccounts
Form1
Caption
Collections's Demo

4.      Declare a collection object in General/Declarations as follows.

Dim Accounts As New Collection

Write code for Add command button. When user clicks on Add button after entering data into text boxes, create an object of Account class and put data entered by user into that object and then add that object to collection using Add method.  Account Number (Ano) will be the key for the item added to collection. Key of the item may be used to retrieve the item from the collection.

You can access an item of collection either by using index of the item or by using Key of the item. The key is specified at the time of adding an item as the second parameter for Add method of the collection. The key must be string type.

The syntax of Add method is:

Add item, key, before, after

The meaning of each parameter is as follows.

Parameter
Meaning
Item
The item to be added to the collection.
Key
The key of the item that is being added to the collection. The key should be a string.
Before
Specifies that the new item should be added to the collection before the specified item. Item is identified either by key or by index.
After
Specifies that the new item should be added to the collection after the specified item. Item is identified either by key or by index.





Note: If before and after are not given in Add method, the new item is added to the end of the collection.

Here is the complete code to add an account object to the collection.

Private Sub cmdAdd_Click()
 Dim acc As New Account
 ' place data into object
 acc.Init CInt(txtAno.Text), txtAhname.Text, txtCb.Text, txtType.Text
 'add object to collection with ANO as the key
 Accounts.Add acc, txtAno.Text
 ClearFields
End Sub
Listing 24.13: Code for Add button.

The code for ClearFields, which is used to empty text boxes in procedure is as follows:
Public Sub ClearFields()
   ' empty all text boxes
   txtAno.Text = ""
   txtAhname.Text = ""
   txtCb.Text = ""
   txtType.Text = ""
End Sub
Listing 24.14: Code for ClearFields procedure.

To list out the item in the collection, enter the following code for Click event of cmdList command button.
Private Sub cmdlist_Click()
Dim acc As Account
  ' clear all values from listbox
  lstAccounts.Clear
  ' populate listbox using values in the collection
  For Each acc In Accounts
     'concatenate all the values
     With acc
        gap = Space(5)
        st = Str(.Ano) & gap & .Ahname & gap
        st = st & Str(.CurBal) & gap & .AccountType
        lstAccounts.AddItem st
     End With
  Next
End Sub
Listing 24.15: Code for List command button.

Note: For Each ... loop is a special loop designed specifically for collections. For more details see chapter 17.

To delete an item, whose account number is entered in txtAno text box, enter the following code for cmdDelete command button.

Private Sub cmdDelete_Click()
 On Error GoTo errlbl
 ' delete the details of the account whose ANO is entered
 ' in txtAno textbox
 Accounts.Remove txtAno.Text
 Exit Sub
errlbl:
 MsgBox "Account Number is not Found"
End Sub
Listing 24:16: Code for Delete command button.

Remove method of the collection takes a single parameter, which is either index of the item to be removed or the key of the item. If it is a string, it is treated as the key. If it is of numeric type, it is treated as index of the item to be removed.

If the given key or index is not found in the collection, a runtime error occurs. So trap the error and display error message.

To get the details of an account, whose account number is entered in txtano text box, enter the following code:

Private Sub cmdSearch_Click()
Dim acc As Account
  On Error GoTo errlbl
  ' get details of the account whose ano is entered
  ' in txtAno textbox
  Set acc = Accounts.Item(txtAno.Text)
  With acc
     txtAno.Text = .Ano
     txtAhname.Text = .Ahname
     txtCb.Text = .CurBal
     txtType.Text = .AccountType
  End With
  Exit Sub
errlbl:
    MsgBox "Account Number not found"
End Sub
Listing 24:17: Code for Search button.

Item method results in runtime error if the given index is not found in the collection. So handle the runtime error and display a message to user.

No comments: