|
|
|
Inheritance
Now that VB.Net supports many object oriented features, lets discuss about Inheritance. Inheritance is the cornerstone of Object Oriented programming. VB.net supports inheritance and I am sure VB6 programmers will welcome this step. Inheritance gives us an ability to define hierarchichal classification of the objects. It enables us to write code once and reuse it in many other derived classes. In classes, the class which is the "parent" is called the "Base Class" and the "child" classes which inherit from the Base class are called "Derived Classes". All derived classes from the base class inherit properties and methods defined with Public or Protected access modifiers.
Once you understand the importance of Inheritance you will love it. Inheritance gives you amazing capability of code re-usage.
For example if you are creating classes for various Vehicles e.g. CCar, CTrain, CPlane etc. Probably all these classes can have some common attributes and methods. So instead of writing duplicate code in all the Classes, it would be nice to have some mechanism by which we can write our code once and get the functionality in many other classes if required. Yes this is exactly what Inheritance gives you.
Using Inheritance you can create the “Base Class” in which you can define some common methods and properties. You can use these later in your derived classes. If you don’t want to use some of the base class methods or properties and instead define new functionality then you can always override the methods. We can override methods of the base class with our own version in derived class implementing the required functionality. Also we can define new methods and properties in a derived class.
Look at the following screenshot. Only AddGas() method is from CCar class and all other methods and member variables are from base class CVehicle.
Now let’s start with real example. In this example I will show you how to create a Base class CVehicle and then how to use its functionality in some other classes CCar, CTrain and CPlane without writing duplicate code in each class.
Step-By-Step Example
- Create a new Windows Application Project - Add new class file (Project- > Add Class) - Copy/Paste the following code in class1.vb |
Click here to copy the following block |
Public Class CVehicle Public Model As String = "" Public Make As String = "" Public MaxMileageWarning As Integer Public TotalMileage As Integer
Private m_IsMaxMileageReached As Boolean = False
Public Event MaxMileageReached(ByVal Sender As CVehicle, ByVal Mileage As Integer)
Public Sub Drive(ByVal Distance As Integer) TotalMileage = TotalMileage + Distance
If MaxMileageWarning > 0 And m_IsMaxMileageReached = False Then If TotalMileage >= MaxMileageWarning Then m_IsMaxMileageReached = True RaiseEvent MaxMileageReached(Me, TotalMileage) End If End If End Sub End Class
Public Class CCar Inherits CVehicle
Sub AddGas() End Sub End Class
Public Class CTrain Inherits CVehicle
Public IsElectricTrain As Boolean
Sub StartEngine() End Sub End Class
Public Class CPlane Inherits CVehicle Sub Land() End Sub
Sub TakeOff() End Sub End Class |
Now let’s look at the example which uses these vehicle classes defined above.
- In the form1 add one command button - Add the following code in form1 |
Click here to copy the following block | Dim WithEvents somecar As New CCar Dim WithEvents sometrain As New CTrain Dim WithEvents someplane As New CPlane
Sub OnMaxMileageWarning(ByVal Sender As CVehicle, ByVal Mileage As Integer) Handles somecar.MaxMileageReached MsgBox(Sender.Make & " " & Sender.Model & " Passed " & Mileage & " Mileages") End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click somecar.Drive(24000) Me.Text = somecar.TotalMileage End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load somecar.Make = "HONDA" somecar.Model = "Accord LX" somecar.MaxMileageWarning = 50000
sometrain.IsElectricTrain = True sometrain.Make = "ABC International" sometrain.Model = "Freight 2278" sometrain.MaxMileageWarning = 200000000
someplane.Make = "Boeing" someplane.Make = "747" someplane.MaxMileageWarning = 100000000 End Sub |
Understanding Overloading and Overriding
Overloadinng :
In a class if two methods have the same name but different signature, it is known as "overloading" (this topic has been covered in Part 1 of this Tutorial herehttp://binaryworld.net/Main/CodeDetail.aspx?CodeId=3927) For example we have Drive() method in CVehicle class which takes one argument. However, if you want to provide another version of Drive() method which takes Mileage, Source and Destination then it becomes an overloaded method. The VB.Net compiler calls the appropriate method based on number of arguments and respective data types. |
If you are defining overloaded methods in the same class then there is no problem. But when overloading a method from a derived class you need to do it by the “Overloads” keyword. If you don’t use “Overloads” keyword you will get compiler warning but your code will compile and run without any problem.
Overriding:
Overriding is a concept of redefining a base class method/property in a derived class. In “Overriding”, the base class method's/property's signature must match with the derived class method's/property's signature. For example, in our CCar Class, by default the base class Drive() method is available. But if you don’t want to use base class Drive() method and want to override it with your own version, then you can use Overriding.
To define method/property for overriding you have to use Overridable keyword in base class and Overrides keyword in derived class. Lets look at the example. |
Click here to copy the following block | Public Class CVehicle Public Overridable Sub Drive(ByVal Distance As Integer) Console.WriteLine("Vehicle drive - " & Ddistance & " Miles") End Sub
End Class
Public Class CCar Inherits CVehicle Public Overrides Sub Drive(ByVal Distance As Integer) Console.WriteLine("Car drive - " & Ddistance & " Miles") End Sub End Class |
How does “Overriding” work?
When you define any method or property using “Overridable” keyword in base class then all subclass methods with “Overrides” keyword are considered as Virtual Methods by VB.net compiler. Virtual methods are called based on object’s reference type and non-virtual methods (regular methods) are called based on variable type.
Let’s look at the following example. |
Click here to copy the following block | Public Class CVehicle Public Overridable Sub Drive(ByVal Distance As Integer) Console.WriteLine("Vehicle drive - " & Ddistance & " Miles") End Sub
Public Sub StartEngine() Console.WriteLine("Vehicle Started...") End Sub End Class
Public Class CCar Inherits CVehicle Public Overrides Sub Drive(ByVal Distance As Integer) Console.WriteLine("Miles") End Sub
Public Sub StartEngine() Console.WriteLine("Car Started...") End Sub End Class |
Now lets see how Virtual Method makes difference in programming. |
Click here to copy the following block | 1 Dim myVehicle as New CVehicle
2 myVehicle.StartEngine() 3 myVehicle.Drive(1000)
4 myVehicle =New CCar()
5 myVehicle.StartEngine() 6 myVehicle.Drive(1000) |
Vehicle Started...
Vehicle drive – 1000 Miles
Vehicle Started...
Car drive – 1000 Miles |
In the above example CVehicle class has 2 methods Drive() and StartEngine().
Drive()method is defined as Overridable and StartEngine() is a normal method. Now if you look at the CCar which has exact same methods as CVehicle class but very important thing to note is “Overrides” keyword used in Drive() method. This tells compiler that Drive() method in CCar is Overrided version of base class.
Now if you look at the output of the code then you will see that line 2 and 3 call methods from CVehicle which is very straight forward. But if you look at the line 5 and 6 then its little confusing because line 5 calls method from CVehicle class and line 6 calls method from CCar class. This is because of we have defined Drive method using “Overrides” keyword (Virtual Method) in CCar class so when compiler calls Drive() method of any object derived from CVehicle it will locate the method based on the object type not the variable type. Variable type of myVehicle is CVehicle but after line 4 it references to CCar object.
Note : Variable of a base class type can always hold a reference to an object of any subclass. This is the reason that variable of System.Object type can hold reference to virtually any type in .Net because all objects (including native datatypes) in .Net are derived from System.Object class.
The Shadow keyword
Suppose, in our CCar class, we don't want to override the Drive() method yet we need to have a Drive() method, what we can do? In Java, we can't do this. In C++, if we have marked the method in base class as virtual, it is also impossible. But, VB.Net introduces the keyword Shadows to mark a method as a non-overriding method and as one which we don't want to use polymorphically. We have the CVehicle and CCar classes as below |
Click here to copy the following block | Public Class CVehicle Public Overridable Sub Drive(ByVal Distance As Integer) Console.WriteLine("Vehicle drive - " & Ddistance & " Miles") End Sub
Public Sub StartEngine() Console.WriteLine("Vehicle Started...") End Sub End Class
Public Class CCar Inherits CVehicle Public Shadows Sub Drive(ByVal Distance As Integer) Console.WriteLine("Miles") End Sub
Public Sub StartEngine() Console.WriteLine("Car Started...") End Sub End Class |
Now if you run the following code then you will see different output |
Since we marked the Drive() method in the CCar class with Shadows, no polymorphism is applied here and the Drive() method of the Shape class is called. If we don't mark the Drive() method with Shadows keyword, we will see the following warning at compile time sub 'Drive' shadows an overridable method in a base class. To override the base method, this method must be declared 'Overrides'.
Shared Methods, Variables and Events
Up to here we have seen that class is a template and you can create an instance of a given class which is also known as “Object”. Each object carries its own copy of member variables. In order to access class methods we must create an instance and after that you can access class methods and variables.
In this section we will see how we can create shared methods and shared variables which can be accessed without creating any instance. In other words shared members are not instance specific but they are global to entire class and only one copy is maintained across all instances of a class.
Shared Variables
Shared member variables can be available to all instances of a given class and any instance can modify the shared member and all other instances will see the modified value.
Let’s look at a quick example. |
Now run the following code to see the result |
Click here to copy the following block | Dim v1, v2, v3 As New CVehicle
CVehicle.TotalVehicle = 0
v1.TotalVehicle = v1.TotalVehicle + 2 Console.Writeline("V1=" & v1.TotalVehicle & "; V2=" & v2.TotalVehicle & "; V3=" & v3.TotalVehicle)
v2.TotalVehicle = v1.TotalVehicle + 2 Console.Writeline("V1=" & v1.TotalVehicle & "; V2=" & v2.TotalVehicle & "; V3=" & v3.TotalVehicle)
v3.TotalVehicle = v1.TotalVehicle + 2 Console.Writeline ("V1=" & v1.TotalVehicle & "; V2=" & v2.TotalVehicle & "; V3=" & v3.TotalVehicle) |
V1=2; V2=2; V3=2
V1=4; V2=4; V3=4
V1=6; V2=6; V3=6 |
Here after creating changing TotalVehicle of each instance we are reading value of TotalVehicle from v1, v2 and v3 and you will see that all objects read the same value because TotalVehicle is a shared member so all instances of CVehicle class accees only one shared copy of TotalVehicle instead of their own copy.
Shared Methods and Properties
As I mentioned earlier that not only we can define shared variables but we can also define shared methods and Properties. In order to access shared method or Properties you don’t need instance of a class, you can directly access shared method or shared property followed by the class name. |
.sharedmethod()
.sharedproperty |
However there are few things to know about shared methods and properties.
Since shared methods and properties are instance specific but global to all instances so you can not access any instance specific member variable from within a shared method or property. You can only access shared members of a class, private variables defined inside the shared method or property and any arguments passed to the method or property.
If we attempt to access an instance variable within a shared method, we'll get a compiler error.
Example: |
Shared Events
As you know that just like variables, properties and method, “event” is another interface element. By default events are not shared means event will be raised for a specific instance. But you can define an event as a shared event so when event is fired all objects can trap that event not only the object that fired the event.
Shared events can be raised from both instance methods and shared methods. Regular events can not be raised by shared methods. Since shared events can be raised by regular methods. Let’s look at some interesting code by which you can define one event handler for all your objects of a given class. |
Click here to copy the following block | Public Class CVehicle Public Make As String Public Model As String Shared m_TotalVehicle As Integer
Public Shared Event NewVehicleAdded(ByVal TotalCount As Integer)
Sub AddNew() m_TotalVehicle = m_TotalVehicle + 1 RaiseEvent NewVehicleAdded(m_TotalVehicle) End Sub End Class |
Now let’s look at the code which uses the shared event |
Click here to copy the following block | Dim v1, v2, v3 As New CVehicle
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load AddHandler CVehicle.NewVehicleAdded, AddressOf OnNewVehicleAdded End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click v1.AddNew() End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click v2.AddNew() End Sub
Sub OnNewVehicleAdded(ByVal TotalCount As Integer) MsgBox("Total count " & TotalCount) End Sub |
In the above example button1 and button2 click event increments the shared counter and each time any instance of CVehicle class calls AddNew shared method, an event is fired and can be trapped by all instances of CVehicle class.
Here I have done little interesting thing. If you look at the AddHandler then you will notice that instead of object I have used class name. This is possible only if you using AddHandler for Shared event. So anytime instance of CVehicle raise NewVehicleAdded event we can trap in our client code. |
|
|
|
Submitted By :
Nayan Patel
(Member Since : 5/26/2004 12:23:06 PM)
|
|
|
Job Description :
He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting. |
View all (893) submissions by this author
(Birth Date : 7/14/1981 ) |
|
|