4.8 Account Class: Initializing Objects with Constructors

As mentioned in Section 4.6, when an object of class Account (Fig. 4.6) is created, its string instance variable name is initialized to null by default. But what if you want to provide an actual name when you create an Account object?

Each class you declare optionally can provide a constructor with parameters that can be used to initialize an object when it’s created. C# requires a constructor call for every object that’s created, so this is the ideal point to initialize an object’s instance variables. The next example enhances class Account (Fig. 4.8) with a constructor that can receive a name and use it to initialize the Name property when an Account object is created (Fig. 4.9). Now that you’ve seen class Account in action, this chapter’s two remaining examples present class Account before class AccountTest.

This version of class Account replaces the private name instance variable and the public Name property from Fig. 4.6 with a public auto-implemented Name property (Fig. 4.8, line 6). This property automatically creates a hidden private instance variable to store the property’s value.

Fig. 4.8 Account class with a constructor that initializes an Account’s name.

Alternate View

  1   // Fig. 4.8: Account.cs
  2   // Account class with a constructor that initializes an Account's name.
  3
  4   class Account
  5   {
  6      public string Name { get; set; } // auto-implemented property
  7
  8      // constructor sets the Name property to parameter accountName's value
  9      public Account(string accountName) // constructor name is class name  
 10      {                                                                     
 11         Name = accountName;                                                
 12      }                                                                     
 13   }

4.8.1 Declaring an Account Constructor for Custom Object Initialization

When you declare a class, you can provide your own constructor to specify custom initialization for objects of your class. For example, you might want to specify a name for an Account object when the object is created, as in line 11 of Fig. 4.9:


Account account1 = new Account("Jane Green");

In this case, the string argument "Jane Green" is passed to the Account object’s constructor and used to initialize the Account’s name. A constructor’s identifier must be the class’s name. The preceding statement requires an Account constructor that can receive a string. Figure 4.8 contains a modified Account class with such a constructor.

Account Constructor Declaration

Let’s walk through the code of the constructor’s declaration (Fig. 4.8, lines 9–12):


public Account(string accountName) // constructor name is class name
{
   Name = accountName;
}

We refer to the first line of each constructor declaration (line 9 in this case) as the constructor header. This constructor receives the string parameter accountName—which represents the name that’s passed to the constructor as an argument. An important difference between constructors and methods is that constructors cannot specify a return type (not even void). Normally, constructors are declared public so they can be used by the class’s client code to initialize objects of the class.

Constructor Body

A constructor’s body is delimited by a pair of braces (lines 10 and 12 of Fig. 4.8) containing one or more statements that perform the constructor’s task(s). In this case, the body contains one statement (line 11) that assigns parameter accountName’s value (a string) to the class’s Name property, thus storing the account name in the object. After line 11 executes, the constructor has completed its task, so it returns to the line of code containing the object-creation expression that invoked the constructor. As you’ll soon see, the statements in lines 11–12 of Main (Fig. 4.9) each call this constructor.

4.8.2 Class AccountTest: Initializing Account Objects When They’re Created

The AccountTest program (Fig. 4.9) initializes two Account objects using the constructor. Line 11 creates and initializes the Account object account1. Keyword new requests memory from the system to store the Account object, then implicitly calls the class’s constructor to initialize the object. The call is indicated by the parentheses after the class name, which contain the argument "Jane Green" that’s used to initialize the new object’s name. Line 11 then assigns the initialized object to the variable account1. Line 12 repeats this process, passing the argument "John Blue" to initialize the name for account2. Lines 15–16 use each object’s Name property to obtain the names and show that they were indeed initialized when the objects were created. The output shows different names, confirming that each Account maintains its own name.

Fig. 4.9 Using the Account constructor to set an Account's name when an Account object is created.

Alternate View

  1   // Fig. 4.9: AccountTest.cs
  2   // Using the Account constructor to set an Account's name
  3   // when an Account object is created.
  4   using System;
  5
  6   class AccountTest
  7   {
  8      static void Main()
  9      {
 10         // create two Account objects
 11         Account account1 = new Account("Jane Green");
 12         Account account2 = new Account("John Blue"); 
 13
 14         // display initial value of name for each Account
 15         Console.WriteLine($"account1 name is: {account1.Name}");
 16         Console.WriteLine($"account2 name is: {account2.Name}");
 17      }
 18   }

account1 name is: Jane Green
account2 name is: John Blue

Default Constructor

Recall that line 10 of Fig. 4.5


Account myAccount = new Account();

used new to create an Account object. The empty parentheses in the expression


new Account()

indicate a call to the class’s default constructor—in any class that does not explicitly declare a constructor, the compiler provides a public default constructor (which always has no parameters). When a class has only the default constructor, the class’s instance variables are initialized to their default values:

  • 0 for numeric simple types,

  • false for simple type bool and

  • null for all other types.

In Section 10.5, you’ll learn that classes can have multiple constructors through a process called overloading.

There’s No Default Constructor in a Class That Declares a Constructor

If you declare one or more constructors for a class, the compiler will not create a default constructor for that class. In that case, you will not be able to create an Account object with the expression new Account() as we did in Fig. 4.5—unless one of the custom constructors you declare takes no parameters.

Software Engineering Observation 4.4

Unless default initialization of your class’s instance variables is acceptable, provide a custom constructor to ensure that your instance variables are properly initialized with meaningful values when each new object of your class is created.

Adding the Constructor to Class Account’s UML Class Diagram

The UML class diagram of Fig. 4.10 models class Account of Fig. 4.8, which has a constructor with a string accountName parameter. The UML models constructors as operations in the third compartment of a class diagram. To distinguish a constructor from the class’s other operations, the UML requires that the word “constructor” be enclosed in guillemets (« and ») and placed before the constructor’s name. It’s customary to list constructors before other operations in the third compartment. In Fig. 4.14, you’ll see a class diagram with both a constructor and an operation in the third compartment.

Fig. 4.10 UML class diagram for Account class of Fig. 4.8.

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

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