Come back to home page

Object Oriented Programming in VB.NET (Part I)

This tutorial is an extension to my last article on Object Oriented Programming. We have already seen the beauty and power of OOP in the last article. In this article, we will see how to implement the features of OOP in VB.NET.

For making it practically useful, I have designed this article in 'step-by-step instruction' fashion. You may follow the steps given below to implement OOP concepts with your own hands!! In the bargain, you will understand the basic concepts of OOP.

For your convenience, I have divided the topic in three parts:

  • Abstraction/Encapsulation (Part 1)
  • Inheritance (Part 2)
  • Polymorphism (Part 3)

This article covers the first part, other two will follow soon (how soon depends on your feedback).

NOTE: If you feel this article deserves votes, please do vote and provide your feedback, it motivates a person to spend time and energy in writing...

This article deals in Abstraction and Encapsulation. Abstraction means hiding complexity and providing a simple interface for things and encapsulation is how we do it programmatically. See previous article on OOP for more explanation.

I have written this article in a way that it is of maximum help to our beginner brothers and sisters. The style is subjective for this purpose. If you do not like my style of writing and want to suggest some change, please provide your feedback, I would surely respect your opinion and try to improve there. If you like the pattern, then also, please do give your feedback...

Preparation

1.  Start Visual Studio and create a new Windows Application.
2.  Add a class; Project | Add Class...
3.  Giver a suitable name to the class. We can use cStudent.vb for this example.

We are going to use this file cStudent.vb to create our class and the Windows Form Form1.vb to create object and use the code written in class.

NOTE:  We can create any number of classes in a class file. In other words, a class file (like cStudent.vb) can hold many classes.

Class and Object

To understand the difference, please refer to the following section from my last tutorial on OOP.

... Classes and Objects ...

You are already familiar with the concept of an Object. An object, as we have already seen, is a piece of code which is capable of handling information and functionality related to it independently. We can visualize objects as small components of a bigger system, which can be grouped together to develop the system. For example, Computer is a system and the Hard Disk, RAM, Motherboard are different objects used in a computer system. Often, the objects represent some entity which is able to exist independently.

If we want to use some object in our program, we only need to know what does this object do and not how it does it….Abstraction again! To use it, we will have to load the object in memory so that it can use the CPU and other resources or simply run! Now, loading an object into memory is called Instantiation, in other words, whenever we load an object we can say we have created an instance of it.

Technically, an object is called an object when it is in an instantiated state or loaded. This is so because then only we can actually use it… But there must be some definition for this object, which describes the functionality of the object. This definition is called the Class. Please note that a class is not an object. It is just a set of instructions telling how an object should work.

To understand this let us take an example. All of you must be familiar with the house map. It contains the details of a how to make a house, where to put windows, where to keep the doors, and how many rooms should be there, of what sizes, etc. Is that ‘map’ the house itself? No. A map is just the instruction set and what we create from it is a house, which is a physical/actual thing made up of cement and concrete which can be used to live in. The same relation exists between a class and an object.

Map \-----\ House
Class \-----\ Object

  • A map is instruction set for the house and similarly class is an instruction set for the object.
  • House is the actual thing we are bothered about and so is the object.
  • Many houses can be created from a map and similarly many objects can be created or instantiated from a class.
  • House occupies some space actually and not the map. Similarly, an Object gets loaded and uses the memory not the class. A class is just a set of instructions which specify how an object should look like and what should it do.

I hope now you have a clear about the class and the objects. An object is a programming unit and class is definition of the object. If still not clear, please discuss - rahul@coder000.com.

It is clear from the above explanation that a class is used for defining an entity in our programs. But, how exactly do we define a class?

Defining a class

Defining a class is very simple. If we want to create a class named cStudent, we use this code (right column):

Class cStudent

End Class

When you add a class module, as described earlier (in preparation section), this code comes by default in the class file. Visual Studio adds the code for defining the class for us. But did you note some difference... 'Public' keyword. I am sure you noted that thing there. This is called access type. Let us take a brief look at some access types. Other access types will be covered later...

Public Class cStudent

End Class

Access Types
Private - If a class is declared with private it is accessible only within the class in which it is defined. (Yes, we can define one class in another in VB.NET)...

Please note that we can use private modifier only when there is some parent class because otherwise it is meaningless to use private keyword.
Class cParent
    Private Class cChild

    End Class
End Class
Friend - If we declare a class with friend modifier, it means that the class is accessible within the program, but not outside it. This means that if a class is declared with Friend keyword, programs other than the one in which this class is defined, will not be able to use it. This is the default access type, that is, if you do not specify an access type, the class will be treated as friend.

Public - No restrictions. The class declared with public keyword can be accessed from anywhere!!

Graphical Representation of Access Types

Back to defining class
So, now we know how to declare a class (we will create a public class in this example):

Public Class cStudent

End Class

What to put in the class? What can we do in a class... Well, we know that a class represents an entity. We can program our class such that it behaves just like the real life entity. This is done through properties, methods and events that we can create within our class...

Now let us first write a simple method in our class and use the class so that it can be clear what exactly we are doing and why are we doing so.

I am sure that you have got this feeling developed in your mind and heart that what we call a class is nothing but virtual representation of a real world entity. When we write student class, we are defining a student!! Once this definition is complete, we can create as many students as we want (instances of student class - objects) and program any scenario in which students are involved... Each student will have its own life!! (Perhaps God created us like this and we are nothing but instances of class Human.... Matrix!!)

If the concept is not crystal clear still, no problem, keep moving, you will understand... or contact me.. :)

So, we are writing a simple behavior of student.... Laugh (Do students laugh??, well, our students laugh.. :)) Public Class cStudent
   
Public Sub Laugh()
        MsgBox(":)")
   
End Sub
End
Class

We have just taught our student to laugh. But this is not the student, this is just a definition for student, that is, it just defines how a student should be. In other words, all students created using this definition will be capable of doing anything defined here (they may not do, but will be capable of doing).

How exactly can we create a student using this definition? For using this class, let us go to the form again. Let us put a button and create an instance of student class on its click event.

Line 1: Declaration
Line 2: Instantiation
Line 3: Calling Method
Line 4: Dereferencing

Private Sub Button1_Click(ByVal sender As  System.Object, ByVal e As System.EventArgs) Handles  Button1.Click
   
Dim objStudent1 As cStudent   'Line 1
    objStudent1 =
New cStudent()  'Line 2
    objStudent1.Laugh()           'Line 3
    objStudent1 =
Nothing         'Line 4
End Sub

Line 1: When we create a student object, we would definitely want to access it. How would you access the object as it will be created in memory? The answer is that we will access the object through a name (reference variable) which will actually be a pointer to the object. The first line tells VB.NET that we want our object variable to be able to point to an object of cStudent (note that there is no object instantiated till this point). objStudent1 is a variable which can point to an object of cStudent class and no other class (well, not exactly..... we will discuss this special case in next article).

Line 2: New keyword is very important in VB.NET. It is used to create an object (in memory) of the specified class (using a specified constructor, to be discussed later) and return its reference. In this line, new keyword creates an object of class cStudent and returns its reference (memory address) to objStudent1. We have already declared objStudent1 as a variable which can hold reference of type cStudent. Now we can access the object through the name/variable objStudent1. This is called instantiation.

NOTE: These two lines can be combined into one:

    Dim objStudent1 As New cStudent()

Line 3: In third line we are calling Laugh method of the object through our reference variable objStudent1. Remember this method is there in the object because it was defined in the class of which this object is an instance. Similarly we can access any member (property, method, etc.) defined in a class using object variable name (objStudent1 in this example) followed by a dot (.) and member name.

Line 4: Till this point, our reference variable objStudent1 holds reference of the object. This line assigns Nothing to objStudent1, that is, it makes it point to nothing!!! This makes our object inaccessible (can't access this object now as objStudent1 points to something else and no reference variable refers to this object) and such objects (which are of no use as we cannot access them) are removed from the memory automatically (that is a different story about Garbage Collection to be covered later...). It is a good practice to dereference the object after they have served their purpose so that they can be removed from the memory.

To make this whole thing clear, I have given a simple graphical representation of what happens in memory, please check it out:

Write this code, run and see...

I am sure that now you have got the feeling of how things are happening, let us move further...

Properties

Let us think for a moment about our student class... How will the objects of this class be identified? Our class must have the capability to handle Student ID, Name, Age, etc.

The solution is simple, we can create public variables in the class to store these properties of a student. 

Public Class cStudent
   
Public Age As
Byte
    .
    .
End Class 
To set the age we will do something like this:

Dim objStudent1 As New cStudent()
objStudent1.Age = 20

Fine. Now consider the following:

Dim objStudent1 As New cStudent()
objStudent1.Age = 200

or

objStudent1.Age = 2000

We would not want the users of our class to be able to set wrong data or invalid data. But there is no way to control this if we allow the users to access the variables directly. So, what is the best solution for this? The answer is Properties.

To store data of our object we would definitely require variables. These variables are called instance variables because they are created for each instance of the class. But, instead of giving direct access to instance variables, we will provide properties to the users of our class to access data. This way we will be able to check and control the value which is assigned.

Therefore, we will make our instance variables private so that they can not be accessed from outside the class: Private iAge As Byte

See, I have used the prefix 'i' before the variable name. I use this to differentiate instance variables from other elements.

Our next step is to create a public property for Age:

Public Property Age() As Byte
    Get
        Return
iAge
   
End Get

   
Set(ByVal Value As Byte)
       
If Value <= 12 Or Value >= 30 Then
           
MsgBox("We do not accept students below 12 years and above 30 years", MsgBoxStyle.Exclamation, "Age not set")
       
Else
           
iAge = Value
       
End If
   
End Set
End Property
To access this property, we will use this code...
    Line 1: Set property - Age
    Line 2: Get property - Age

Dim objStudent1 As New cStudent()
objStudent1.Age = 16

MsgBox("The present age is: " & objStudent1.Age)

A property has two parts: Get and Set.

The get part of a property is accessed when the value of property is read like in line 3 above. Therefore, we need to return a value (which we want our users to read) when get is invoked. In this case, we return the value of iAge.

Set part of the property is called when the user assigns some value to the property. The assigned value is passed to the Set code. Now see, we have decided to store the age in iAge variable. However, we do not want the users to set any age they want. Therefore, we have defined the criterion and applied it in the property. The value which users assign to the property is accessible to us through Value parameter. We can check the value and decide if we really want to assign it to iAge (as we have done above). This way we can maintain the integrity of our class.

One more thing. We have used Public and Private in our instance variable declaration to make it accessible or inaccessible to the code outside the class. Public and private are access types or access specifiers which define the scope of a variable. Please check the following to see the available access types and the scope defined for each one.

Private - available only to the code within our class
Friend - available only to the code within the project
Protected - available only to classes that inherit from our class
Public - available to code inside and outside our class or project
NOTE: See the diagram given above while discussing the scope of classes

Let's return back to properties. We have already learned how to create a property. What if you do not want the user to set or change a property but want to allow him/her to be able to get/see it. Yes, I am talking about readonly properties.

ReadOnly and WriteOnly Properties
To understand this, let us assume that there is a property called TotalCreditsEarned and it is calculated by some complex method and users are not allowed to change its value directly. However, users can check/read the TotalCreditsEarned property. Let us assume that TotalCreditsEarned is calculated by some method and is stored in a private variable called iTCE. Using this information, we can write a read only property: Public ReadOnly Property TotalCreditsEarned() As Int16
   
Get
        Return
iTCE
   
End Get
End
Property

Please note in the above code that to make a property read only, we use the ReadOnly keyword in property declaration and remove the set part of the property (we do not need this anyway in a read only property).

Simple? Similarly, we can make a property write only by using the keyword WriteOnly instead of readonly and defining only the set portion.

If you have any questions or doubts  in this, mail me.

Public WriteOnly Property WOP() As DataType
   
Set(ByVal Value As DataType)
       
'do something
   
End Set
End
Property
Parameterized Properties

 

Now let us take one example. Suppose each student is evaluated on the basis of marks in VB, ASP and Java. To get or set these marks, we will have to create three private variables and three properties. Right?

Let us see a better way to do so. We will keep 3 variables to store the values (yes, we can use array also), however, we will define only one property to access these variables. But the problem is - how will we know which subject user wants to access? See the code:

I suppose code is quite self explanatory... Note that we have used a parameter (subj as string) to handle this case.

Private iMarksVB As Single
Private iMarksASP As Single
Private iMarksJava As Single

Public Property Marks(ByVal subj As String) As Single
    Get
       
Select Case subj
           
Case "VB"
               
Return iMarksVB
           
Case "ASP"
               
Return iMarksASP
           
Case "Java"
               
Return iMarksJava
       
End Select
   
End Get

    Set(ByVal Value As Single)
       
Select Case subj
           
Case "VB"
                iMarksVB = Value
           
Case "ASP"
                iMarksASP = Value
           
Case "Java"
                iMarksJava = Value
       
End Select
   
End Set
End Property

To access this property, we will have to write something like this:
Line 1: Set Property - Marks
Line 2: Get Property - Marks

Dim objStudent1 As New cStudent()
Dim MarksInVB As Single
objStudent1.Marks("VB") = 55.5 'Line 1
MarksInVB = objStudent1.Marks("VB") ' Line 2
Enumeration

There is a problem in above code. User must know that there are three subjects (VB, ASP, Java) and must use strings to represent them. If the spelling or letter case is wrong, then? VB.NET provides a very beautiful construct to handle such cases and I like to use it as much as possible - Enumeration.

Have you ever noticed that while using the MsgBox function a list of all available buttons or icons appear automatically when you need to enter it? If not, then first of all do the following:

Open a project and write - Msgbox "something" - in it and then put a comma (,). Did you see a list of all available buttons.

Wouldn't it be nice if our class user gets a list like this (containing VB, ASP, Java, etc.) when he/she accesses the Marks property? And would you not like that when you are writing code for Get and Set, you also get the list while using Select Case statement?

This reduces chances of error many times and provides a quick and easy interface for us and our users to work.

Please see the code which demonstrates how to provide these features using enumeration.

In the code note the following things:

  • Enumerations are created using the ENum keyword
  • They can be used as type while declaring variables or parameters for methods or properties

Private iMarksVB As Single
Private iMarksASP As Single
Private iMarksJava As Single

Public Enum eMarks
    VB
    ASP
    Java
End Enum

Public Property Marks(ByVal subj As eMarks) As Single
    Get
       
Select Case subj
           
Case eMarks.VB
               
Return iMarksVB
           
Case eMarks.ASP
               
Return iMarksASP
           
Case eMarks.Java
               
Return iMarksJava
       
End Select
   
End Get

    Set(ByVal Value As Single)
       
Select Case subj
           
Case eMarks.VB
                iMarksVB = Value
           
Case eMarks.ASP
                iMarksASP = Value
           
Case eMarks.Java
                iMarksJava = Value
       
End Select
   
End Set
End Property

To use this property, see the code given here... (The list of all available subjects comes automatically wherever this parameter is used, for example, while using the property or while defining the property)
Line 1: Set Property - Marks
Line 2: Get Property - Marks
objStudent1.Marks(cStudent.eMarks.VB) = 55.5
MarksInVB=objStudent1.Marks(cStudent.eMarks.VB)

Write this code and try it out yourself once...

Default Properties

We need to write the following to access Marks property:

objStudent1.Marks(cStudent.eMarks.VB)

If we make Marks property the default property, we will be able to access it like this:

objStudent1(cStudent.eMarks.VB)

Please see the code. Note that we have used Default keyword to make our property default. Simple. So we do not need to do anything to our property, except adding the keyword Default, to make it default property. Just a matter of one word!! Default Public Property Marks(ByVal subj As eMarks) As Single
...
...
End Property

Please note some obvious facts about properties:

  • There can be only one default property in a class.
  • Properties with no required parameters cannot be declared Default. Therefore, the property which we want to make default must have at least one parameter.

This was all about properties. Let us move to methods in detail now.

Methods
We have already seen how to create a simple method above. Let us consider it again: Public Sub Laugh()
    MsgBox(":)")
End Sub

Note the keyword Public here. It is an access specifier. Public means that the scope of this method is public, that is, we can call it from anywhere. Private access type limits the scope to the class in which the method is defined and Friend limits the access to the project in which the method is defined. I hope this must be clear by now.

Methods can be of two types:

  • Sub-routines: Methods which do not return any value; keyword used to define - Sub
  • Functions: Methods that return some value; keyword used to define - Function
You have already seen how to define and use a sub-routine above. Check out functions now:

Note that we have used the keyword Function to define a function. The return type is specified in the definition itself. To return the result of the function, we use the Return keyword followed by the value we want to return.

Public Function AverageMarks() As Single
    Return
(iMarksVB + iMarksASP + iMarksJava)/3
End
Function
If we want to use parameters in functions or sub-routines we can define the method as below:

Public Function FindPercentage(ByVal subj As eMarks) As Single
   
Dim result As Single
   
Select Case subj
       
Case eMarks.VB
            result = iMarksVB * 100 / 150
       
Case eMarks.ASP
            result = iMarksASP * 100 / 150
       
Case eMarks.Java
            result = iMarksJava * 100 / 150
   
End Select
    Return
result
End Function

Simple!! If you have any doubts, contact me.

Optional Parameters

Look at the function above. We have assumed that the maximum marks for each subject are 150. If we want to give the user a choice to specify the maximum marks and if the user does not want we want to use 150, then what is the solution? Solution is function with optional parameters. Check the code:

Note that in the code we have used an optional parameter MaxMarks. If a parameter is declared optional, the user may or may not enter a value for this. If the value is not specified by the user, default value is taken (150 in our case). It is compulsory to specify the default value for the optional parameters.

A method can have any number of optional parameters, however, it should be noted that optional parameters must be the last in parameter list of a method.

Public Function FindPercentage(ByVal subj As eMarks, Optional ByVal MaxMarks As Single = 150) As Single
   
Dim result As Single
   
Select Case subj
       
Case eMarks.VB
            result = iMarksVB * 100 / MaxMarks
       
Case eMarks.ASP
            result = iMarksASP * 100 / MaxMarks
       
Case eMarks.Java
            result = iMarksJava * 100 / MaxMarks
   
End Select
    Return
result
End Function
To use this method, we can use following code:
Line 1: Default value of MaxMarks would be taken, that is, MaxMarks=150
Line 2: User specified value is assigned to MaxMarks, that is, MaxMarks=100
objStudent1.FindPercentage(cStudent.eMarks.VB)
objStudent1.FindPercentage(cStudent.eMarks.VB, 100)
One last thing about methods. We can pass objects as parameters to a method and also a method can return an object. To do this we just need to specify the class name in the method declaration (just as we did for enumeration). If you have any doubts in this, contact me.
Shared Members
So far we have seen that the variables defined in a class are created for each instance and hence are called instance variables. Now, if we want to keep track of number of instances created then how can we do so. Here come shared variables. Shared variables are variables which are shared by all instances. In other words, we can say that shared variables belong to the class and not the object.

Similarly there can be properties and methods which do not depend on any object data. These may depend on shared data. Therefore, shared methods and properties cannot access instance variables, but they can use shared variables.

Since shared members belong to the class and not the object, we do not need to create an instance in order to use shared members. We can simply access them as follows:

Class.SharedMember

An example of shared method is MessageBox.Show. Here, Show is the shared member of MessageBox class.

Now, how to define shared members. Very simple. Simply put the keyword 'Shared' after the access type while declaring variables, properties, methods and events.

I have not given any code example here because I am sure that you have already understood. However, if you want some example, please do not hesitate at all to contact me.

For more discussion, you may contact me friends... :)

Delegates
Planning to cover delegates in next article...
Events
We all have done programming based on events. In this example also, we have used the Click Event of button. What are events? Events are a mechanism through which the creator of class gives an opportunity to the user of class to write code when something (some event) happens.

To understand the application of this concept, let us assume that our class has a Save method which saves some data into a file. When the data is saved we want to notify our class user and allow him/her to perform further action, that is, write code which he/she wants to execute when data is saved. This gives our user great independence in performing whatever action he/she wants when data is saved, like simply showing a message box to the end-user or calling another method or copy the file in which data is saved for backup, etc.

Did you note that there are a number of actions which user might want to perform when data is saved (the list can go up to infinity). Therefore, we cannot assume while designing a class that what action our class user might want to perform on some particular event and so it is wise to expose an event for the user to handle in a way he/she desires.

Creating Events
The first step in creating an event is declaration. See the code. This line defines a public event named Saved. And remember there is no code because we are not going to write it!! If you want to add arguments to the event, you can mention them in the same way as we do for methodd. Pretty simple... If doubts, contact me... Public Event Saved()
Once an event is declared, the next step is to raise the event or fire the event at appropriate moment. This is done through RaiseEvent statement. Whenever we wish to fire an event, we use this statement. In this example, just after saving the data in Save method of the class. When the user calls the Save method, it saves the data and when data is completely saved, it fires the Saved event which is to be handled by the user. If you have declared event with arguments, pass the appropriate values in the arguments. These arguments will be available to the user of the class in event handler... If doubts, do not hesitate to contact me... Public Sub Save()
   
'code to save the
    'data
   
RaiseEvent Saved()
End Sub

To use this event, we need to do two things:

  • Use WithEvents keyword while declaring the object of the class (we can instantiate the class in the same line using New keyword). See code...
  • Make the object global, that is, declare the object outside our method directly within the class.
Dim WithEvents objStudent1 As New cStudent()

To write the code to handle the event, we have to write an event procedure. An event procedure is nothing but a method which is called when the event is fired. But how can we associate a method with an event. One way is using Handles keyword. This is the way the events are normally handled (our click event procedure also uses this way).

Just write the method which you want to execute when event fires. Just add Handles objectName.EventName at the end of method declaration to associate that method with the event. However, this method must have the same number and type of arguments as declared in the event which the method has to handle (if the event has arguments)...

If you want .NET IDE to automatically generate the method declaration, you can select the object from object list and then select the event from the event list, just as you do to write event procedure for other objects like button, textbox, etc.

Private Sub objStudent1_Saved() Handles objStudent1.Saved
   
'Do whatever you want when data is saved
   
MsgBox("Data Saved!!!")
End
Sub
Handling Multiple Events

Now, let us assume that we want to perform the same action when two different events occur. That is, we want to associate the same method with more than one events. Well, this can be done very easily in VB.NET. Just write all the events a method has to handle saparated with comma (,). Keep in mind that the rules of using Handles statement remain the same.

If we want a method handleIt() to handle two events Saved and Loaded of object objStident1, we will use this code.

Private Sub handleIt() Handles objStudent1.Saved, objStudent1.Loaded
   
'Do whatever you want when data is saved
   
MsgBox("Data Saved!!!")
End Sub
Event Association at run time

In all the examples above, we have associated a method with some event at design time. There can be situations in which you do not know which method handles which event, or, you create an object at run time and want to associate one of its event with some method. How can this be done? Before explaining this let us consider another case to feel the need to associate at run time.

I have one application which loads the images from a folder at run time and shows them as thumbnails in picture boxes. When user clicks on any of the image a form opens with that particular image in full size. When the user clicks on this new form, the form unloads. Did you understand what I want to say?

Now what I do to show the full view is, I create a form at run time, add picture box to it and show the selected picture in it. Remember all this is done through code at runtime. Now how to associate the method to unload this form with Picturebox's click event...

This is what we are trying to see here. To associate an event with some method at run time, we use AddHandler statement. And to dissociate any event with its handler method at run time, we use RemoveHandler statement.

Suppose we have a method XYZ(). To associate this method with objStudent1 object's Saved method at run time, we will use the following code:

AddHandler objStudent1.Saved, AddressOf XYZ

and to dissociate, we will use following line:

RemoveHandler objStudent1.Saved, AddressOf XYZ

As you can see, the first parameter used above is the event name and second parameter is address of the method!! Simple??
Well, we cannot discuss AddressOf in this series in detail....

I hope that events are clear now, however, if you have any concerns or queries, you are always welcome to contact me and ask or discuss.

Constructor/Termination
Friends, the article has already grown in size more than what was expected. Please allow me to include these topics in the following tutorial.

Here we will conclude our first tutorial in the OOPS in VB.NET series. Please remember following things:

  • If you have any doubts or questions OR if you want to discuss something, please feel free to contact me without hesitation. I will be glad to discuss with you and help you. We can discuss either through the discussion page here or you can contact me at rahul@coder000.com
  • If you think this series or this article is helpful, please give your feedback and votes if you feel... This gives motivation and enthusiasm, you know.

Happy coding!!