Classes
A class is a collection of objects of similar type. Once a class is defined, any number of objects can be
created which belong to that class. Visual Basic .NET comes with thousands of built-in classes which are
ready to be used.
The class framework is the primary means of implementing OOP in [Link] which provides the
programmer with many techniques for exploiting the three main principles of OOP—encapsulation,
inheritance, and polymorphism.
Classes are much more powerful because they have many more tools available to them. These tools
include constructor methods for creating new objects and the capabilities of having multiple methods
with the same name and inheriting the definition of one class in another class.
Class Methods
A method is the term used in OOP to refer to subroutines and functions. A class can contain both data
members and subprograms that operate on these data. A method is tied to a particular object whereas
a function is tied only to the program where it is defined and used.
Methods may or may not return a value, so they are defined as subroutines or functions.
The Constructor Method
A constructor method is a subroutine that initializes the data members of a class to a set of values
passed to the method when a class object is declared.
A constructor method is passed one or more values to be assigned to one or more of the data members
of the class.
Constructor methods are always named New. Constructors make working with class easier since you can
assign values to all the data members of the class in one line of code, rather than having to assign each
data member individually after the class object is declared. Because constructor methods do not return
a value, they are defined as subroutines.
Now let’s look at an example that uses a constructor and methods (defined as subroutines in this case).
Example 1: BankAccount Class with constructor and methods
Public Class BankAccount
' Fields
Public AccountName As String
Public AccountNumber As String
Private PIN As Integer
Private Balance As Double
' Constructor
Public Sub New(name As String, accNo As String, bal As Double, pinNo As Integer)
AccountName = name
AccountNumber = accNo
Balance = bal
PIN = pinNo
End Sub
1
' Deposit Method
Public Sub Deposit(amount As Double)
Balance += amount
[Link]("Deposited: " & amount)
End Sub
' Withdraw Method with validation
Public Sub Withdraw(amount As Double)
If amount > Balance Then
[Link]("Insufficient balance!")
Else
Balance -= amount
[Link]("Withdrawn: " & amount)
End If
End Sub
' Check Balance Method
Public Sub CheckBalance()
[Link]("Current Balance: " & Balance)
End Sub
' Transfer Method
Public Sub Transfer(receiver As BankAccount, amount As Double)
If amount > Balance Then
[Link]("Transfer failed!")
[Link]("Insufficient balance.")
Else
Balance -= amount
[Link] += amount
[Link]("Transferred " & amount & " to " &
[Link])
End If
End Sub
' Display Method
Public Sub DisplayInfo()
[Link]("Account Name: " & AccountName)
[Link]("Account Number: " & AccountNumber)
[Link]("Balance: " & Balance)
End Sub
End Class
Sub Main()
' Creating first account using constructor
Dim acc1 As New BankAccount("Alex Joseph", "ACC1001", 50000, 1234)
' Creating second account
Dim acc2 As New BankAccount("Mary John", "ACC2001", 30000, 4321)
[Link]("FIRST ACCOUNT DETAILS")
[Link]()
[Link]()
' Deposit money
[Link](10000)
' Withdraw money
[Link](20000)
' Attempt to withdraw too much money
[Link](100000)
[Link]()
2
' Check balance
[Link]()
[Link]()
' Transfer money
[Link](acc2, 5000)
[Link]()
[Link]("FIRST ACCOUNT AFTER TRANSFER")
[Link]()
[Link]()
[Link]("SECOND ACCOUNT AFTER RECEIVING MONEY")
[Link]()
[Link]()
End Sub
To call the method, we use the dot notation with which we’re already familiar from using .NET
Framework class objects such as [Link], [Link], etc. Now let’s look at an example that
uses methods that are defined as both functions and subroutines.
Example 2: Advanced Banking System with constructors and methods
Module Module1
'=========================
' BANK CLASS
'=========================
Public Class Bank
Private Accounts(9) As BankAccount
Private AccountCount As Integer = 0
' Create Account
Public Sub CreateAccount()
If AccountCount >= [Link] Then ‘array can store only ten accounts
[Link]("Bank is full!")
Exit Sub
End If
Dim name As String
Dim accNo As String
Dim balance As Double
Dim pin As Integer
[Link]("Enter name: ")
name = [Link]()
[Link]("Enter account number: ")
accNo = [Link]()
[Link]("Enter opening balance: ")
balance = [Link]()
[Link]("Enter PIN: ")
pin = [Link]()
'Accounts(AccountCount) = New BankAccount(name, accNo, balance, pin)
Dim acc As New BankAccount(name, accNo, balance, pin)
Accounts(AccountCount) = acc
AccountCount += 1
[Link]("Account created successfully!")
End Sub
' Display Accounts
Public Sub DisplayAccounts()
If AccountCount = 0 Then
3
[Link]("No accounts found.")
Exit Sub
End If
Dim i As Integer
For i = 0 To AccountCount - 1
[Link]("===================")
Accounts(i).DisplayInfo()
Next
End Sub
' Deposit
Public Sub DepositMoney()
Dim accNo As String
Dim amount As Double
[Link]("Enter account number: ")
accNo = [Link]()
Dim acc As BankAccount = FindAccount(accNo)
If acc Is Nothing Then
[Link]("Account not found.")
Exit Sub
End If
[Link]("Enter amount: ")
amount = [Link]()
[Link](amount)
End Sub
' Withdraw
Public Sub WithdrawMoney()
Dim accNo As String
Dim pin As Integer
Dim amount As Double
[Link]("Enter account number: ")
accNo = [Link]()
Dim acc As BankAccount = FindAccount(accNo)
If acc Is Nothing Then
[Link]("Account not found.")
Exit Sub
End If
[Link]("Enter PIN: ")
pin = [Link]()
If [Link](pin) = False Then ‘method defined as a function
[Link]("Incorrect PIN.")
Exit Sub
End If
[Link]("Enter amount: ")
amount = [Link]()
[Link](amount)
End Sub
' Transfer
Public Sub TransferMoney()
Dim senderNo As String
Dim receiverNo As String
Dim amount As Double
[Link]("Sender account: ")
senderNo = [Link]()
[Link]("Receiver account: ")
receiverNo = [Link]()
Dim sender As BankAccount = FindAccount(senderNo)
Dim receiver As BankAccount = FindAccount(receiverNo)
4
If sender Is Nothing Or receiver Is Nothing Then
[Link]("Invalid account.")
Exit Sub
End If
[Link]("Enter amount: ")
amount = [Link]()
[Link](receiver, amount)
End Sub
' Search Method
Private Function FindAccount(accNo As String) As BankAccount
Dim i As Integer
For i = 0 To AccountCount - 1
If Accounts(i).AccountNumber = accNo Then
Return Accounts(i)
End If
Next
Return Nothing
End Function
End Class
'=========================
' BANK ACCOUNT CLASS
'=========================
Public Class BankAccount
Public AccountName As String
Public AccountNumber As String
Private Balance As Double
Private PIN As Integer
Private Transactions(19) As String
Private TransactionCount As Integer = 0
Private DepositCount As Integer = 0
Private WithdrawCount As Integer = 0
' Constructor
Public Sub New(name As String, accNo As String, bal As Double, pinNo As Integer)
AccountName = name
AccountNumber = accNo
Balance = bal
PIN = pinNo
AddTransaction("Account opened with " & bal)
End Sub
' Deposit
Public Sub Deposit(amount As Double)
If amount <= 0 Then
[Link]("Invalid amount.")
Exit Sub
End If
Balance += amount
DepositCount += 1
AddTransaction("Deposited " & amount)
[Link]("Deposit successful.")
End Sub
' Withdraw
Public Sub Withdraw(amount As Double)
If amount > Balance Then
[Link]("Insufficient balance.")
ElseIf amount <= 0 Then
[Link]("Invalid amount.")
Else
Balance -= amount
5
WithdrawCount += 1
AddTransaction("Withdrawn " & amount)
[Link]("Withdrawal successful.")
End If
End Sub
' Transfer
Public Sub Transfer(receiver As BankAccount, amount As Double)
If amount > Balance Then
[Link]("Transfer failed.")
Else
Balance -= amount
[Link] += amount
AddTransaction("Transferred " & amount & " to " & [Link])
[Link]("Received " & amount & " from " & AccountName)
[Link]("Transfer successful.")
End If
End Sub
' PIN Validation
Public Function ValidatePIN(enteredPIN As Integer) As Boolean
Return enteredPIN = PIN
End Function
' Add Transaction
Private Sub AddTransaction(message As String)
If TransactionCount < [Link] Then
Transactions(TransactionCount) = message
TransactionCount += 1
End If
End Sub
' Display Information
Public Sub DisplayInfo()
[Link]("Name: " & AccountName)
[Link]("Account Number: " & AccountNumber)
[Link]("Balance: " & Balance)
[Link]("Deposits: " & DepositCount)
[Link]("Withdrawals: " & WithdrawCount)
[Link]("--- Transactions ---")
Dim i As Integer
For i = 0 To TransactionCount - 1
[Link](Transactions(i))
Next
End Sub
End Class
Sub Main()
Dim bank As New Bank()
Dim choice As Integer
Do
[Link]("====== BANK MENU ======")
[Link]("1. Create Account")
[Link]("2. Display Accounts")
[Link]("3. Deposit")
[Link]("4. Withdraw")
[Link]("5. Transfer")
[Link]("6. Exit")
[Link]("Enter choice: ")
choice = [Link]()
[Link]()
6
Select Case choice
Case 1
[Link]()
Case 2
[Link]()
Case 3
[Link]()
Case 4
[Link]()
Case 5
[Link]()
Case 6
[Link]("Program ended.")
Case Else
[Link]("Invalid choice!")
End Select
[Link]()
Loop Until choice = 6
[Link]()
End Sub
End Module
SAMPLE PROGRAM OUTPUT
====== BANK MENU ======
1. Create Account
2. Display Accounts
3. Deposit
4. Withdraw
5. Transfer
6. Exit
Enter choice: 1
Enter name: Alex Joseph
Enter account number: ACC1001
Enter opening balance: 50000
Enter PIN: 1234
Account created successfully!
====== BANK MENU ======
1. Create Account
2. Display Accounts
3. Deposit
4. Withdraw
5. Transfer
6. Exit
Enter choice: 1
Enter name: Mary John
Enter account number: ACC2001
Enter opening balance: 30000
Enter PIN: 4321
7
Account created successfully!
====== BANK MENU ======
1. Create Account
2. Display Accounts
3. Deposit
4. Withdraw
5. Transfer
6. Exit
Enter choice: 2
===================
Name: Alex Joseph
Account Number: ACC1001
Balance: 50000
Deposits: 0
Withdrawals: 0
--- Transactions ---
Account opened with 50000
===================
Name: Mary John
Account Number: ACC2001
Balance: 30000
Deposits: 0
Withdrawals: 0
--- Transactions ---
Account opened with 30000
====== BANK MENU ======
1. Create Account
2. Display Accounts
3. Deposit
4. Withdraw
5. Transfer
6. Exit
Enter choice: 3
Enter account number: ACC1001
Enter amount: 10000
Deposit successful.
====== BANK MENU ======
1. Create Account
2. Display Accounts
3. Deposit
4. Withdraw
5. Transfer
6. Exit
Enter choice: 4
Enter account number: ACC1001
Enter PIN: 1234
8
Enter amount: 15000
Withdrawal successful.
====== BANK MENU ======
1. Create Account
2. Display Accounts
3. Deposit
4. Withdraw
5. Transfer
6. Exit
Enter choice: 5
Sender account: ACC1001
Receiver account: ACC2001
Enter amount: 5000
Transfer successful.
====== BANK MENU ======
1. Create Account
2. Display Accounts
3. Deposit
4. Withdraw
5. Transfer
6. Exit
Enter choice: 2
===================
Name: Alex Joseph
Account Number: ACC1001
Balance: 40000
Deposits: 1
Withdrawals: 1
--- Transactions ---
Account opened with 50000
Deposited 10000
Withdrawn 15000
Transferred 5000 to Mary John
===================
Name: Mary John
Account Number: ACC2001
Balance: 35000
Deposits: 0
Withdrawals: 0
--- Transactions ---
Account opened with 30000
Received 5000 from Alex Joseph
====== BANK MENU ======
1. Create Account
2. Display Accounts
3. Deposit
9
4. Withdraw
5. Transfer
6. Exit
Enter choice: 6
Program ended.
Here we are assuming we want the class to have Public access, which means the class can be accessed
anywhere in a program that imports the class.
The degree to which we can access a data member in a class is determined by the member’s access
modifier. An access modifier (example Public and Private) is placed before a variable name in a variable
declaration statement.
A data member declared as Public can be accessed by any program or any class. A data member
declared Private, in contrast, can be accessed only by code written inside the class where the data
member is declared.
Encapsulation
Encapsulation is bundling data and methods together inside a class and controlling direct access to the
data.
What does controlling direct access to the data means?
Consider the previous banking Program. Look at this part:
Private Balance As Double
Private PIN As Integer
These variables are encapsulated because of Private access modifier. Private means:
• accessible only inside the class
• inaccessible outside the class
So external code (whether from the Sub main or another class) cannot directly do this:
[Link] = 1000000
or
[Link] = 9999
This protects the object from illegal modification. Imagine if these variables were not encapsulated then
balance were public (ie: assume balance was declared as: Public Balance As Double ), Then balance
will be accessible from the outside the class, so anyone could change the balance. Such that by typing:
[Link] = -900000
This destroys data integrity. Hence encapsulation protects the data Instead of changing balance directly
the user must use controlled methods Deposit(), Withdraw() and Transfer(). These methods contain
rules and validation as shown in the following program:
10
Public Sub Withdraw(amount As Double)
If amount > Balance Then
[Link]("Insufficient balance.")
ElseIf amount <= 0 Then
[Link]("Invalid amount.")
Else
Balance -= amount
WithdrawCount += 1
AddTransaction("Withdrawn " & amount)
[Link]("Withdrawal successful.")
End If
End Sub
The balance is protected because:
• users cannot directly edit balance
• they must pass through validation
Encapsulation allows the class to enforce business rules. Without encapsulation users could bypass rules
completely.
PIN Protection
Private PIN As Integer
This hides the PIN from outside access. Correct access is through ValidatePIN() function. Example:
Public Function ValidatePIN(enteredPIN As Integer) As Boolean
Return enteredPIN = PIN
End Function
The real PIN stays hidden. This is strong encapsulation.
Encapsulation = Data + Methods Together
Inside BankAccount class there is DATA which are Balance, PIN and AccountNumber. There is also
METHODS which are Deposit(), Withdraw(), Transfer() and ValidatePIN(). The class wraps data
and operations on the data into one secure unit. That wrapping is encapsulation.
Encapsulation Benefits in Your Program
Benefit Example
Security PIN hidden
Validation Prevent over-withdrawal
Data integrity Balance cannot be corrupted
Controlled access Use methods instead of direct editing
Easier maintenance Rules centralized in methods
Therefore encapsulation hide internal implementation and expose controlled access.
11
Properties Methods
This is another advanced encapsulation improvement. Professional programmers often use Properties.
Property method definitions begin with an access modifier that declares the method Public, so that
client code will have access to them.
Here is the method heading for the Balance property of the BankAccount class:
Public Property Balance As Double
There are two parts to the body of a Property method—the Get accessor and the Set accessor. These
accessors are automatically provided by the compiler when you write the Property method heading. You
don’t have to define them, but you must implement them in your methods.
The Get accessor is used to retrieve the value of a class data member. Often the only code in the
accessor is a Return statement that specifies a data member name.
The Set accessor allows the client code to assign a value to a class data member. The accessor comes
with a built-in parameter value that you must use, called value. Although you can write extra code to
perform error checking or some other function, a Set accessor is commonly just an assignment
statement that assigns the parameter value to a class data member.
In fact, using properties is considered a better OOP design than exposing fields directly. Here’s is an
example of program with improved encapsulation using properties method:
Public Class BankAccount
' Private fields
Private _accountName As String
Private _accountNumber As String
Private _balance As Double
Private _pin As Integer
' Property for Account Name
Public Property AccountName As String
Get
Return _accountName
End Get
Set(value As String)
If value <> "" Then
_accountName = value
End If
End Set
End Property
' Property for Account Number
Public Property AccountNumber As String
Get
Return _accountNumber
End Get
Set(value As String)
If value <> "" Then
_accountNumber = value
End If
End Set
End Property
' Property for Balance
Public ReadOnly Property Balance As Double
12
Get
Return _balance
End Get
End Property
'helper method
Private Sub UpdateBalance(amount As Double)
_balance += amount
End Sub
' Property for PIN
Public Property PIN As Integer
Get
Return _pin
End Get
Set(value As Integer)
If value >= 1000 And value <= 9999 Then
_pin = value
Else
[Link]("Pin cannot be below 1000 and above 9999")
End If
End Set
End Property
Public Sub ChangePin(oldPin As Integer)
PIN = oldPin
End Sub
Public Sub New(name As String, accNo As String, bal As Double, pinNo As Integer)
AccountName = name
AccountNumber = accNo
_balance = bal
'note here we assign value to property method and not directly to class data member
PIN = pinNo
End Sub
Public Sub New()
AccountName = ""
AccountNumber = ""
_balance = 0.0
End Sub
Public Sub Deposit(amount As Double)
If amount <= 0 Then
[Link]("Invalid deposit amount.")
Exit Sub
End If
UpdateBalance(amount)
[Link]("Deposit successful.")
End Sub
Public Sub Withdraw(amount As Double)
If amount <= 0 Then
[Link]("Invalid amount.")
ElseIf amount > Balance Then
[Link]("Insufficient balance.")
Else
'Balance = Balance - amount
UpdateBalance(-amount)
[Link]("Withdrawal successful.")
End If
End Sub
Public Sub Transfer(receiver As BankAccount, amount As Double)
If amount <= 0 Then
[Link]("Invalid transfer amount.")
13
Exit Sub
End If
If amount > Balance Then
[Link]("Insufficient balance.")
Exit Sub
End If
' Reduce sender balance
UpdateBalance(-amount)
' Increase receiver balance
[Link](amount)
[Link]("Transfer successful.")
End Sub
End Class
Sub Main()
Dim ba1 As New BankAccount("abc", 123, 300000, 2222)
Dim ba2 As New BankAccount()
[Link] = "cde"
[Link] = 456
[Link] = 1111
[Link]("=================Account Details ========================== ")
[Link]("Accountname for ba1 is " & [Link])
[Link]("Accountnumber for ba1 is " & [Link])
[Link]("Balance for ba1 is " & [Link])
[Link]("PIN for ba1 is " & [Link])
[Link]()
[Link]("Accountname for ba2 is " & [Link])
[Link]("Accountnumber for ba2 is " & [Link])
[Link]("Balance for ba2 is " & [Link])
[Link]("PIN for ba2 is " & [Link])
[Link]("=================End of accounts details=================")
[Link](50000)
'You can only read balance but you cannot edit it directly from sub main
[Link]("Balance for ba2 after deposit is " & [Link])
'only way to edit balance is through Deposit, Withdraw and Transfer method
[Link](100000)
[Link]("The balance for ba1 after withdraw is " & [Link])
[Link](ba2, 50000)
[Link]("Balance for ba1 after transfer to ba2 is " & [Link])
[Link]("Balance for ba2 after receiving from ba1 is " & [Link])
'now try to withdraw big amount than balance
[Link](150000)
[Link]("Balance for ba2 after withdraw is " & [Link])
[Link](5555)
'now try to put invalid PIN
[Link](333)
[Link]("New PIN for ba1 after changing is " & [Link])
[Link]("New PIN for ba2 after changing is " & [Link])
[Link]()
End Sub
OUTPUT
=================Account Details ==========================
Accountname for ba1 is abc
Accountnumber for ba1 is 123
Balance for ba1 is 300000
PIN for ba1 is 2222
14
Accountname for ba2 is cde
Accountnumber for ba2 is 456
Balance for ba2 is 0
PIN for ba2 is 1111
=================End of accounts details=================
Deposit successful.
Balance for ba2 after deposit is 50000
Withdrawal successful.
The balance for ba1 after withdraw is 200000
Transfer successful.
Balance for ba1 after transfer to ba2 is 150000
Balance for ba2 after receiving from ba1 is 100000
Insufficient balance.
Balance for ba2 after withdraw is 100000
Pin cannot be below 1000 and above 9999
New PIN for ba1 after changing is 2222
New PIN for ba2 after changing is 5555
Notice that the constructor now benefits from the validation already built into the properties (ie. In the
statement, PIN = pinNo ). Also the property ensures that PIN cannot become above 9999 and below
1000. Because before writing new PIN to class data member (_pin), it is first validated by PIN property
method.
Why Properties Are Better Than Public Fields?
Using public field (ie: Public PIN As Integer) anyone can write to class data member (such that:
[Link] = 123) hence no protection. But using property (ie: Public Property PIN As Integer).
[Link] = 123
is rejected by the property’s validation logic because it is less than 1000.
Properties provide:
• controlled reading/writing
• extra validation
Read-Only Property method
Using read-only balance property method is even better. Instead of:
Public Property Balance As Double
you can make it read-only from outside:
Public ReadOnly Property Balance As Double
Get
Return _balance
End Get
End Property
15
Then create a private helper method:
Private Sub UpdateBalance(amount As Double)
_balance += amount
End Sub
Now balance can only change through Deposit(), Withdraw() and Transfer() methods. This is
stronger encapsulation.
Private Helper Method
This method changes the balance. Notice:
• Positive amount → increases balance
• Negative amount → decreases balance
Why Use UpdateBalance() helper method?
Without it:
_balance += amount
would appear repeatedly in Deposit(), Withdraw() and Transfer() methods. Using a helper method
avoids duplication because only method call (ie. UpdateBalance(amount)) will appear in these
methods, as shown in the program above.
Note: The helper method assumes that the caller has already validated everything. This works if every
programmer always remembers to validate before calling UpdateBalance(). However, that is not a
strong design because mistakes happen.
Better Design: Make UpdateBalance Defensive
Instead of trusting callers, make the helper method protect itself, as shown below:
Private Sub UpdateBalance(amount As Double)
If (_balance + amount) < 0 Then
[Link]("Balance cannot become negative.")
End If
_balance += amount
End Sub
Now subroutine call like UpdateBalance(-2000) displays an error message instead of corrupting the
balance. If helper method implement validation as shown above then there is a single point of control
for balance changes. Which lead to making maintenance easier.
Hence encapsulation protect object data by restricting direct access and allowing controlled interaction
through methods.
16
Encapsulation Level Comparison
Approach Encapsulation Level
Public fields Poor
Private fields + Public methods Good
Private fields + Properties Better
Private fields + Validated Properties + Controlled Excellent
Methods
17