Chapter 26. Initializing Objects

Most of the time when you create an object, you need to initialize its properties. For example, you generally wouldn't create an Employee object without at least setting its FirstName and LastName properties. The following code shows how you might initialize an Employee object:

' Make an Employee named Alice.
Dim alice As New Employee()
alice.FirstName = "Alice"
alice.LastName = "Archer"
alice.Street = "100 Ash Ave"
alice.City = "Bugsville"
alice.State = "CO"
alice.Zip = "82010"
alice.EmployeeId = 1001
alice.MailStop = "A-1"

Though this is relatively straightforward, it is a bit tedious. Creating and initializing a bunch of Employees would take a lot of repetitive code. Fortunately, Visual Basic provides alternatives that make this task a little easier.

In this lesson you learn how to initialize an object's properties as you create it. You also learn how to make constructors that make initializing objects easier.

INITIALIZING OBJECTS

Visual Basic provides a simple syntax for initializing an object's properties as you create it. Create the object as usual with a New statement. Next add the keyword With and a pair of braces holding the property assignments. Each assignment should include a dot, a property name, an equals sign, and the value you want to give to the property.

For example, the following code creates an Employee object named Bob. The statements inside the braces initialize the object's properties.

' Make an Employee named Bob.
Dim bob As New Employee() With
{
    .FirstName = "Bob",
    .LastName = "Baker",
    .Street = "200 Beach Blvd",
    .City = "Bugsville",
    .State = "CO",
    .Zip = "82010",
    .EmployeeId = 1002,
    .MailStop = "B-2"
}

Note

An initializer can only initialize properties that the code can access. For example, if a property is private, the initializer cannot set its value.

CONSTRUCTORS

Initializers are handy and easy to use but sometimes you might like some extra control over how an object is created. Constructors give you that extra control.

A constructor is a subroutine named New that is executed when an object is created. The constructor executes before the code that creates the object gets hold of it. The constructor can perform any setup tasks that you want to get the object ready for use. It can look up data in databases, prepare data structures, and initialize properties.

The next two sections describe two kinds of constructors: parameterless constructors and parameterized constructors. The section after those explains how one constructor can invoke another to avoid duplicated work.

Parameterless Constructors

A constructor can take parameters just like any other method to help it in its setup tasks. A parameterless constructor takes no parameters, so it's somewhat limited in what it can do.

Note

Parameterless constructors are also sometimes called empty constructors.

For example, suppose the Manager class has a DirectReports property, which is a list of Employees that report to a given manager. A parameterless constructor cannot build that list because it doesn't know which employees to put in it. It can, however, initialize the DirectReports to an empty list as shown in the following code:

Public Class Manager
    Inherits Employee

    Public Property DirectReports As List(Of Employee)

    ' Initialize the DirectReports list.
    Public Sub New()
        DirectReports = New List(Of Employee)()
    End Sub
End Class

You implicitly invoke a parameterless constructor anytime you create an object without using any parameters. For example, the following code creates a new Manager object. When this code executes, control jumps briefly to the parameterless constructor so it can prepare the object for use.

Dim fred As New Manager()

Note that Visual Basic creates a default public parameterless constructor for you if you make a class that doesn't define any constructors explicitly. This code is hidden behind the scenes so you can't see it in any of your project's files.

If you give the class any constructors, Visual Basic doesn't create the default constructor. In that case, if you want a parameterless constructor, you must make it yourself.

Parameterized Constructors

Parameterless constructors are useful but fairly limited because they don't have much information to go by. To give a constructor more information, you can make it take parameters just like you can with any other method.

One simple type of parameterized constructor uses its parameters to initialize properties. For example, you could make a constructor for the Person class that takes the person's first and last names as parameters. The constructor could then set the object's FirstName and LastName properties.

Why would you bother doing this when you could use an initializer? First, the syntax for using a constructor is slightly more concise than initializer syntax. The following code uses a constructor that takes six parameters to initialize a Person's properties:

Dim cindy As New Person("Cindy", "Carstairs",
    "300 Clam Ct", "Bugsville", "CO", "82010")

Compare this code to the earlier snippet that used initializers to initialize an Employee object. This version is more concise, although it's less self-documenting because it doesn't explicitly list the property names.

The second reason you might prefer to use a parameterized constructor instead of an initializer is that a constructor can perform all sorts of checks that an initializer cannot. For example, a constructor can validate its parameters against each other or against a database. An Employee class's constructor could take an employee ID as a parameter and check a database to verify that the employee really exists.

A constructor can also require that certain parameters be provided. For example, a Person constructor could require that the first name and last name parameters be provided. If you rely on initializers, the program could create a Person that has no first name or last name.

To make a constructor that takes parameters, simply add the parameters as you would for any other method. The following code shows a constructor for the Person class that uses its parameters to initialize the new Person object's properties:

' Initializing constructor.
Public Sub New(ByVal newFirstName As String,
 ByVal newLastName As String, ByVal newStreet As String,
 ByVal newCity As String, ByVal newState As String,
 ByVal newZip As String)

    ' Verify that FirstName and LastName are present.
    If newFirstName Is Nothing Then
        Throw New ArgumentException("FirstName is required")
    End If
    If newFirstName.Length = 0 Then
        Throw New ArgumentException("FirstName cannot be blank")
    End If
    If newLastName Is Nothing Then
        Throw New ArgumentException("LastName is required")
    End If
    If newLastName.Length = 0 Then
        Throw New ArgumentException("LastName cannot be blank")
    End If

    ' Initialize the properties.
    FirstName = newFirstName
    LastName = newLastName
    Street = newStreet
    City = newCity
    State = newState
    Zip = newZip
End Sub

INVOKING OTHER CONSTRUCTORS

You can give a class many different constructors as long as they have different parameter lists (so Visual Basic can tell them apart). For example, you might give the Person class a parameterless constructor; a second constructor that takes first name and last name as parameters; and a third constructor that takes first name and last name, street, city, state, and zip code as parameters.

Often when you give a class multiple constructors, some of them perform the same actions. In the Person example, the constructor that initializes first name, last name, street, city, state, and zip code probably does the same things that the second constructor does to initialize just first name and last name (plus more).

You can also find overlapping constructor functionality when one class inherits from another. For example, suppose the Person class has FirstName and LastName properties. The Employee class inherits from Person and adds some other properties such as EmployeeId and MailStop. The Person class's constructor initializes the FirstName and LastName properties, something that the Employee class's constructors should also do.

Having several methods perform the same tasks makes debugging and maintaining code harder. Fortunately, Visual Basic provides a way you can make one constructor invoke another.

To make a constructor use another constructor in the same class, simply invoke it as if it were any other subroutine. The only catch is that you need to call the constructor Me.New, not just New.

Note

Note that if constructor A invokes constructor B, then constructor A must do so before doing anything else.

For example, the following code shows three constructors for the Person class that invoke each other. The code that invokes other constructors is shown in bold.

' Parameterless constructor.
Public Sub New()
    ' General initialization if needed...
End Sub

' Initialize FirstName and LastName only.
Public Sub New(ByVal newFirstName As String, ByVal newLastName As String)
    ' Call the parameterless constructor.
    Me.New()

    ' Initialize the properties.
    FirstName = newFirstName
    LastName = newLastName
End Sub

' Initialize all properties.
Public Sub New(ByVal newFirstName As String, ByVal newLastName As String,
 ByVal newStreet As String, ByVal newCity As String,
 ByVal newState As String, ByVal newZip As String)
    ' Call the previous constructor to initialize FirstName and LastName.
    Me.New(newFirstName, newLastName)

    ' Initialize the other properties.
    Street = newStreet
    City = newCity
    State = newState
    Zip = newZip
End Sub

The first constructor is a parameterless constructor. In this example it doesn't do anything.

The second constructor takes first and last names as parameters. It invokes the parameterless constructor and then initializes the FirstName and LastName properties. This version doesn't verify that FirstName and LastName are present and nonblank because a program could use the parameterless constructor to get around that restriction anyway.

The third constructor takes name and address parameters. It invokes the previous constructor to initialize FirstName and LastName. (That constructor in turn invokes the parameterless constructor.) It then initializes the object's remaining properties.

You can use a similar syntax to invoke a parent class constructor by simply replacing Me.New with MyBase.New.

For example, the Employee class inherits from the Person class. The following code shows three of the class's constructors:

Public Sub New()
    ' Invoke the Person constructor.
    MyBase.New()
End Sub

Public Sub New(ByVal newFirstName As String, ByVal newLastName As String)
    ' Invoke the Person constructor.
    MyBase.New(newFirstName, newLastName)
End Sub

Public Sub New(ByVal newFirstName As String, ByVal newLastName As String,
 ByVal newStreet As String, ByVal newCity As String,
 ByVal newState As String, ByVal newZip As String,
 ByVal newEmployeeId As Integer, ByVal newMailStop As String)
    ' Invoke the Person constructor.
    MyBase.New(newFirstName, newLastName, newStreet,
        newCity, newState, newZip)

    ' Initialize the remaining properties.
    EmployeeId = newEmployeeId
    MailStop = newMailStop
End Sub

The first constructor is parameterless. It invokes its parent class's parameterless constructor by using MyBase.New().

The second constructor takes first name and last name parameters and invokes the Person class's constructor, which takes two strings as parameters.

The final constructor takes eight parameters, invokes the Person class's six-parameter constructor to initialize most of the object's properties, and then initializes the last two properties (which are not inherited from the Person class) itself.

Note

Notice how the constructors invoke other constructors by using Me.New or MyBase.New followed by a parameter list. Visual Basic uses the parameter list to determine which constructor to invoke. That's why you cannot have more than one constructor with the same kinds of parameters. For example, if two constructors took a single String as a parameter, how would Visual Basic know which one to use?

TRY IT

In this Try It, you enhance the Person, Employee, and Manager classes you built for the Try It in Lesson 25. In this Try It, you add constructors to make initializing objects easier.

Note

You can download the code and resources for this Try It from the book's web page at www.wrox.com or www.vb-helper.com/24hourvb.html. You can find the files in the Lesson26 folder.

Lesson Requirements

In this lesson:

  • Copy the program you built for the Try It in Lesson 25 (or download the version that's available on the book's web site).

  • Give the Person class a parameterless constructor. Make it print a message to the Output window indicating that a new Person is being created.

  • Give the Person class a second constructor that initializes all of the class's properties. Make it invoke the parameterless constructor and display its own message.

  • Make similar constructors for the Employee and Manager classes.

  • Remove the buttons from the main form and make the program create Person, Employee, and Manager objects using each of the constructors.

  • Run the program, close it, and examine the Output window messages to see if they make sense.

Hints

  • Make the constructors invoke each other where possible to avoid duplicate work.

  • When the main program uses parameterless constructors, use object initialization to set the objects' properties.

Step-by-Step

  • Copy the program you built for the Try It in Lesson 25 (or download the version that's available on the book's web site).

    1. This is relatively straightforward.

  • Give the Person class a parameterless constructor. Make it print a message to the Output window indicating that a new Person is being created.

    1. The Person class's parameterless constructor should look something like this:

      ' Constructors.
      Public Sub New()
          Console.WriteLine("Person()")
      End Sub
  • Give the Person class a second constructor that initializes all of the class's properties. Make it invoke the parameterless constructor and display its own message.

    1. This constructor should look something like this:

      ' Initialize all properties.
      Public Sub New(ByVal newFirstName As String,
       ByVal newLastName As String, ByVal newStreet As String,
       ByVal newCity As String, ByVal newState As String,
       ByVal newZip As String)
          Me.New()
      
          ' Initialize the other properties.
          Street = newStreet
          City = newCity
          State = newState
          Zip = newZip
          Console.WriteLine("Person(parameters)")
      End Sub
  • Make similar constructors for the Employee and Manager classes.

    1. The following code shows the Employee class's constructors:

      ' Constructors.
      Public Sub New()
          MyBase.New()
      
          Console.WriteLine("Employee()")
      End Sub
      
      ' Initialize all properties.
      Public Sub New(ByVal newFirstName As String,
       ByVal newLastName As String,
       ByVal newStreet As String, ByVal newCity As String,
       ByVal newState As String, ByVal newZip As String,
      ByVal newEmployeeId As Integer, ByVal newMailStop As String)
          MyBase.New(newFirstName, newLastName, newStreet, newCity,
              newState, newZip)
      
          ' Initialize the other properties.
          EmployeeId = newEmployeeId
          MailStop = newMailStop
          Console.WriteLine("Employee(parameters)")
      End Sub
    2. The following code shows the Manager class's constructors:

      ' Constructors.
      Public Sub New()
          MyBase.New()
      
          Console.WriteLine("Manager()")
      End Sub
      
      ' Initialize all properties.
      Public Sub New(ByVal newFirstName As String,
       ByVal newLastName As String,
       ByVal newStreet As String, ByVal newCity As String,
       ByVal newState As String, ByVal newZip As String,
       ByVal newEmployeeId As Integer, ByVal newMailStop As String,
       ByVal newDepartmentName As String)
          MyBase.New(newFirstName, newLastName, newStreet, newCity,
              newState, newZip,
              newEmployeeId, newMailStop)
      
          ' Initialize the other properties.
          DepartmentName = newDepartmentName
          Console.WriteLine("Manager(parameters)")
      End Sub
  • Remove the buttons from the main form and make the main program create Person, Employee, and Manager objects using each of the constructors.

    1. The following code creates objects in this way:

      ' Persons.
      Console.WriteLine("Creating Paula")
      Dim paula As New Person() With
      {
          .FirstName = "Paula",
          .LastName = "Perch",
          .Street = "100 Ash Ave",
          .City = "Bugsville",
          .State = "CO",
          .Zip = "82010"
      }
      
      Console.WriteLine("Creating Pete")
      Dim pete As New Person("Pete", "Pearson",
          "2871 Arc St", "Bugsville ", "CO", "82010")
      ' Employees.
      Console.WriteLine("Creating Edna")
      Dim edna As New Employee() With
      {
          .FirstName = "Edna",
          .LastName = "Evers",
          .Street = "200 Beach Blvd",
          .City = "Bugsville",
          .State = "CO",
          .Zip = "82010",
          .EmployeeId = 1002,
          .MailStop = "B-2"
      }
      
      Console.WriteLine("Creating Edward")
      Dim edward As New Employee("Edward", "Evers",
          "129 Bold Blvd", "Bugsville", "CO", "82010", 1002, "B-2")
      
      ' Managers.
      Console.WriteLine("Creating Mindy")
      Dim mindy As New Manager() With
      {
          .DepartmentName = "Research",
          .EmployeeId = 1001,
          .MailStop = "MS-10",
          .FirstName = "Mindy",
          .LastName = "Marvel",
          .Street = "2981 East Westlake Blvd",
          .City = "Bugsville",
          .State = "CO",
          .Zip = "82010"
      }
      
      Console.WriteLine("Creating Mike")
      Dim mike As New Manager("Mike", "Masco",
          "1298 Elm St", "Bugsville", "CO", "82010",
          1002, "MS-20", "Development")
  • Run the program, close it, and examine the Output window messages to see if they make sense.

    1. The following text shows the program's output. You can see which constructors were executed for each object.

      Creating Paula
      Person()
      Creating Pete
      Person()
      Person(parameters)
      Creating Edna
      Person()
      Employee()
      Creating Edward
      Person()
      Person(parameters)
      Employee(parameters)
      Creating Mindy
      Person()
      Employee()
      Manager()
      Creating Mike
      Person()
      Person(parameters)
      Employee(parameters)
      Manager(parameters)

Note

Please select Lesson 26 on the DVD to view the video that accompanies this lesson.

EXERCISES

  1. Copy the program you built in Lesson 23, Exercise 3 (or download Lesson 23's version from the book's web site). Change the main program and the ComplexNumber class so they use initializers to prepare ComplexNumber objects.

  2. Copy the program you built for Exercise 1. Give the ComplexNumber class a constructor that initializes the new number's real and imaginary parts. Modify the program as needed to use this constructor.

  3. Copy the program you built for Lesson 24's Try It (or download the TryIt24 program from the book's web site). Give the BankAccount class a constructor that guarantees that you cannot create an instance with an initial balance under $10. Change the main program so it uses this constructor.

  4. Copy the program you built for Exercise 3. Now that the program sets the initial balance via a constructor and updates it via the Credit and Debit methods, it no longer needs to set the balance directly. To make the code safer, make Balance a read-only property.

    Note

    You can find solutions to this lesson's exercises in the Lesson26 folder inside the download available on the book's web site at www.wrox.com or www.vb-helper.com/24hourvb.html.

EXERCISES
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset