HOME  |    TRAINING  |   FREE TUTORIALS   |   JOBS
Find out more about our new RSS feed.
FREE Tutorial
VB.NET PROGRAMMING PART 3 - INHERITANCE

CATEGORY
SEARCH OUR OTHER TUTORIALS

DESCRIPTION

While the OO features of VB have been very powerful and useful, we have been held back in many cases by the lack of inheritance in the language. Inheritance is the ability of a class to gain the interface and behaviors of an existing class. The process by which this is accomplished is called subclassing.


This free tutorial is a sample from the book VB.NET Programming with the Public Beta.


When we create a new class that inherits the interface and behaviors from an existing class, we have created a subclass of the original class. This is also known as an "is-a" relationship, where the new class "is-a" type of original class.

There is a lot of terminology surrounding inheritance - much of it redundant. The original class, from which we inherit interface and behavior is known by the following interchangeable terms:

  • Parent class
  • Superclass
  • Base class

The new class that inherits the interface and behaviors is known by the following interchangeable terms:

  • Child class
  • Subclass

Inheritance is also sometimes called generalization. In fact this is the term used within the Universal Modeling Language (UML) - the most commonly used object diagramming notation.

Inheritance is often viewed through the lens of biology, where, for example, a dog is a canine and a canine is a mammal. Hence, by being a canine, a dog inherits all the attributes and behavior of a mammal. While useful for visualization, these analogies only go so far.

For interested object-oriented aficionados, VB.NET does not allow multiple inheritance - where a subclass is created by inheriting from more than one parent class. This feature is not supported by the .NET runtime and thus is not available from VB.NET. VB.NET does allow deep inheritance hierarchies where a class is subclassed from a class that is subclassed, but it doesn't allow a class to be subclassed from multiple parent classes all at once.

We can contrast inheritance, an "is-a" relationship, with another type of parent-child relationship - the "has-a" relationship. This is also known as aggregation or containment.

In a "has-a" relationship, the parent object owns one or more of the child objects, but the child objects are of different types from the parent. For instance, an Invoice has-a LineItem. The LineItem object isn't subclassed from Invoice - it is an entirely different class that just happens to be owned by the Invoice parent.

This distinction is important, because the terms parent and child are used frequently when working with objects - sometimes when referring to inheritance and sometimes when referring to aggregation. It is important to understand which is which or things can get very confusing.

Within this section, we'll use the terms parent, child, and subclass - all in the context of inheritance.

Implementing Basic Inheritance

To explore inheritance, consider a business example with a sales order that has line items. We might have product line items and service line items. Both are examples of line items, but both are somewhat different as well. While we could certainly implement ProductLine and ServiceLine classes separately, they'd have a lot of common code between them. Redundant code is hard to maintain, so it would be nicer if they could somehow directly share the common code between them.

This is where inheritance comes into play. Using inheritance, we can create a LineItem class that contains all the code common to any sort of line item. Then we can create ProductLine and ServiceLine classes that inherit from LineItem - thus automatically gaining all the common code - including interface and implementation in an OO form.

A simple LineItem class might appear as:

Public Class LineItem
Private mintID As Integer
Private mstrItem As String
Private msngPrice As Single
Private mintQuantity As Integer

Public Property ID() As Integer
 Get
  Return mintID
 End Get
 Set
  mintID = value
 End Set
End Property

Public Property Item() As String
 Get
  Return mstrItem
 End Get
 Set
  mstrItem = Value
 End Set
End Property

Public Property Price() As Single
 Get
  Return msngPrice
 End Get
 Set
  msngPrice = Value
 End Set
End Property

Public Property Quantity() As Integer
 Get
  Return mintQuantity
 End Get
 Set
  mintQuantity = Value
 End Set
End Property

Public Function Amount() As Single
 Return mintQuantity * msngPrice
End Function
End Class

This class has things common to any line item - some basic data fields and a method to calculate the cost of the item.

If a line item is for a product, however, we might have additional requirements. The Item value should probably be validated to make sure it refers to a real product, and perhaps we want to provide a product description as well:

Public Class ProductLine
Inherits LineItem

Private mstrDescription As String

Public ReadOnly Property Description() As String
 Get
  Return mstrDescription
 End Get
End Property

Public Sub New(ByVal ProductID As String)
 Item = ProductID
 ' load product data from database
 mstrDescription = "Test product description"
End Sub
End Class

Note the use of the Inherits statement.

 
Inherits LineItem

It is this statement that causes the ProductLine class to gain all the interface elements and behaviors from the LineItem class. This means that we can have client code like this:

Protected Sub Button1_Click(ByVal sender As Object, _
 ByVal e As System.EventArgs)
Dim pl As ProductLine

pl = New ProductLine("123abc")
MessageBox.Show(pl.Item)
MessageBox.Show(pl.Description)
End Sub

This code makes use of both the Item property (from the LineItem class) and the Description property from the ProductLine class. Both are equally part of the ProductLine class, since it is a subclass of LineItem. Likewise, a line item for a service might have a date for when the service was provided, but otherwise be the same as any other line item: Public Class ServiceLine Inherits LineItem Private mdtDateProvided As Date Public Sub New() Quantity = 1 End Sub Public Property DateProvided() As Date Get Return mdtDateProvided End Get Set mdtDateProvided = Value End Set End Property End Class

Again, notice the use of the Inherits statement that indicates this is a subclass of the LineItem class. The DateProvided property is simply added to the interface gained from the LineItem class.

Preventing Inheritance

By default any class we create can be used as a base class from which other classes can be created. There are times when we might want to create a class that cannot be subclassed. To do this we can use the NotInheritable keyword in our class declaration:

Public NotInheritable Class ProductLine

End Class

When this keyword is used, no other code may use the Inherits keyword to create a subclass of our class.

Inheritance and Scoping

When we create a subclass through inheritance, the new class gains all the Public and Friend methods, properties, and variables from the original class. Anything declared as Private in the original class will not be directly available to our code in the new subclass.

The exception to this is the New method. Constructor methods must be re-implemented in each subclass. We'll discuss this in more detail later in the chapter.

For instance, we might rewrite the Amount methods from the LineItem class slightly:

Public Function Amount() As Single
Return CalcAmount
End Function

Private Function CalcAmount() As Single
Return fQuantity * fPrice
End Function

With this change, we can see that the Public method Amount makes use of a Private method to do its work.

When we subclass LineItem to create the ServiceLine class, any ServiceLine object will have an Amount method because it is declared as Public in the base class. The CalcAmount method, on the other hand, is declared as Private and so neither the ServiceLine class nor any client code will have any access to it.

Does this mean the Amount method will break when called through the ServiceLine object? Not at all. Since the Amount method's code resides in the LineItem class, it has access to the CalcAmount method even though the ServiceLine class can't see the method.

For instance, in our client code we might have something like this:

Protected Sub Button1_Click(ByVal sender As Object, _
 ByVal e As System.EventArgs)
Dim sl As ServiceLine

sl = New ServiceLine()
sl.Item = "delivery"
sl.Price = 20
sl.DateProvided = Now

MsgBox(sl.Amount, MsgBoxStyle.Information, "Amount")
End Sub

The result is displayed in a message box, thus illustrating that the CalcAmount method was called on our behalf even though neither our client code, nor the ServiceLine code directly made the call.

Continued...


NEXT PAGE



5 RELATED COURSES AVAILABLE
MICROSOFT VISUAL BASIC V6 INTRODUCTION
To go from the fundamentals of Visual Basic programming to the threshold of Advanced level. Gaining in depth prog....
MICROSOFT VISUAL BASIC V6 ADVANCED - ACCESS BACKEND
To cover a series of advanced programming tasks and to fully command the VB programming language. Microsoft acces....
MICROSOFT VISUAL BASIC V6 ADVANCED - ORACLE BACKEND
To cover a series of advanced programming tasks and to fully command the VB programming language. Oracle is used ....
MICROSOFT VISUAL BASIC 5.0 PROFESSIONAL INTRODUCTION
To provide readers with a solid foundation upon which to build Windows applications using Visual Basic 5. Readers....
MICROSOFT VISUAL BASIC 5.0 ENTERPRISE EDITION SYSTEMS DEVELOPMENT
This course provides detailed knowledge on how to design and write applications using Visual Basic 5.0 enterprise....
 
0 RELATED JOBS AVAILABLE
CONTACT US
Thursday 8th January 2009  © COPYRIGHT 2009 - VISUALSOFT