AddThis Social Bookmark Button

Print

VB.NET OOP Part 2 - Understanding Constructors
Pages: 1, 2

Initialization With Constructors

One of the main uses of constructors is for data initialization. When you create an instance of a class using the New keyword, the compiler does some initialization in the following order:



  • Calls the base class' constructor.
  • Initializes class-level variables.
  • Executes the rest of the class' constructor.

As an example, consider the Manager class below:

Related Reading

Learning Visual Basic .NET
By Jesse Liberty


Public Class Manager : Inherits Employee
  Private id As Integer = 88

  Public Sub New(ByVal name As String)
    MyBase.New(name)
    System.Console.WriteLine("Manager's constructor.")
  End Sub
End Class

First, MyBase.New(name) will be called. Then it will initialize the id private field with the value 88. Finally, the compiler calls the WriteLine method, as in:


System.Console.WriteLine("Manager's constructor.")

A constructor gives the user of your class a chance to pass a value for the initialization. For example, consider the following code:


Public Class Manager : Inherits Employee
  Private nameField As String
  Public Sub New(ByVal name As String)
    nameField = name
    System.Console.WriteLine("Manager's constructor.")
  End Sub
End Class

Here the nameField variable is initialized in the constructor. The user of the class can pass a value for the nameField. For instance, here is the code to pass "John" for the nameField variable:


Dim manager As Manager
manager = New Manager("John")

And, here is how you pass "Kevin" to the Manager object:


Dim manager As Manager
manager = New Manager("Kevin")

If a class-level variable needs to be initialized in a constructor and the constructor happens to have an argument with an identical name with the class-level variable, the argument will hide the class-level variable. To access the class-level variable from inside the constructor, use the Me keyword. For example, the following Manager class' constructor has an argument with the same name as a class-level variable, and uses the Me keyword to access the class-level variable.


Public Class Manager : Inherits Employee
  Private name As String
  Public Sub New(ByVal name As String)
    Me.name = name
    System.Console.WriteLine("Manager's constructor.")
  End Sub
End Class

Multiple Constructors

A class can have multiple constructors to give the user flexibility in constructing an object. For example, in the following Manager class there are two constructors. One is a no-argument constructor and one that accepts a String.


Public Class Manager
  Private nameField As String
  Public Sub New()
    'give nameField a default value
    nameField = "Tony"
  End Sub

  Public Sub New(ByVal name As String)
    nameField = name
  End Sub
End Class

Here, the user can use either constructor. If the user does not know or does not want to pass a name value, then he/she can use the no-argument constructor. Otherwise, the second constructor can be used. Even with constructors that accept different arguments, oftentimes they execute the same code. Look at the following:


Public Class Manager
  Private nameField As String

  Public Sub New()
    'give nameField a default value
    nameField = "Tony"
    System.Console.WriteLine("I am the manager.")
  End Sub

  Public Sub New(ByVal name As String)
    nameField = name
    System.Console.WriteLine("I am the manager.")
  End Sub
End Class

Both constructors execute the following line:


System.Console.WriteLine("I am the manager.")

And in a typical class, there could be multiple lines of code that need to be run in each of the class constructor. Having the same set of code in two or more different places is not wise, because if you need something changed, you need to update it in more than one place. A common technique is to put the code in one constructor and call that constructor from the other constructors. Now the Manager class' no-argument constructor calls the other constructor:


Public Class Manager
  Private nameField As String

  Public Sub New()
    'default value for nameField is Tony
    Me.New("Tony")
  End Sub

  Public Sub New(ByVal name As String)
    nameField = name
    System.Console.WriteLine("I am the manager.")
  End Sub

End Class

Using a constructor for initialization also simplifies the code at the client side. For example, a Manager class has two fields: name and id. You can either let the user access the name and id fields by making those fields public or by creating a property for each field, or you can create a constructor that accepts two arguments. Without the constructor, the user code would be:


Dim manager As Manager
manager = New Manager()
manager.id = 77
manager.name = "Tony"

With a constructor, it would be simpler:


Dim manager As Manager
manager = New Manager(77, "Tony")

Forcing an Object to Have a Specific Type

The other use of constructors is to force an object to have a specific characteristic or behavior. Consider for example the following Person class:


Public Class Person
  Private age As Integer
  Private male As Boolean 'true indicates a man, false a woman
End Class

Without any explicit constructor, the only constructor the Person class has is a no-argument constructor. However, all objects constructed using the New keyword will have its male field False, therefore indicating that the Person is a female. Expectedly, there will be a method or property that the user can call to set the value of the male field. If the user forgets to call this method, however, the resulting object can have invalid values.

Using a constructor that accepts a boolean, such as in the following Person class, will solve the problem.


Public Class Person
  Private age As Integer
  Private male As Boolean

  Public Sub New(ByVal male As Boolean)
    Me.male = male
  End Sub
End Class

Now the user of your class must supply a boolean for every Person object constructed. There is no way the user can forget to set this value because the only constructor the Person class has requires a boolean.

Summary

In this article, you have learned about constructors. In brief, constructors can be used for:

  • Initialization.
  • Restricting direct instantiation in the Singleton pattern (discussed in a separate article).
  • Determining the type of object that can be created.

Budi Kurniawan is a senior J2EE architect and author.


Return to ONDotnet.com