Team LiB
Previous Section Next Section

Instance Constructors

When we talked about instantiating objects in the previous chapter, you may have been curious about the interesting syntax involved with the new operator:

Student x = new Student();

In particular, you may have wondered why there were parentheses tacked onto the end of the statement. It turns out that when we instantiate an object via the new operator, we're actually invoking a special type of function member called an instance constructor. An instance constructor literally constructs (instantiates) a brand-new object by allocating enough program memory to house the object's attributes.

Default Instance Constructors

It turns out that if we don't explicitly declare any instance constructors for a class, C# automatically provides a default parameterless instance constructor for that class. The default instance constructor will initialize any attributes of the class to their zero-equivalent values. So, even though we may have designed a class with no constructors whatsoever:

public class Student
{
  // Attributes.

  private string name;
  // other details omitted

  // Properties/methods (but NO EXPLICIT CONSTRUCTORS!).
  public string Name {
    get {
      return name;
    }
    set {
      name = value;
    }
  }

  // etc.
}

we are still able to write client code as follows:

Student s1 = new Student(); // We're calling the default constructor.

because we are using the default parameterless instance constructor.

Writing Our Own Constructors

We needn't merely rely on C# to provide us with a default constructor; we can also write constructors of our own design. When writing our own constructors, note that the header for a constructor is a bit different from that of methods:

   public           Student         ()
accessibility   constructor   name comma-separated list of formal parameters,
modifier, but   must   match the enclosed in parentheses
no return type! class name (parentheses may be left empty)

Points to note:

  • A constructor's name must be exactly the same as the name of the class for which we're writing the constructor—we have no choice in the matter.

  • We can't specify a return type for a constructor, because by definition a constructor returns a reference to a newly created object of the type represented by the class.

  • A parameter list, enclosed in parentheses, is provided for a constructor header as with method headers; and, as with method headers, it may be left empty if appropriate.

Another oddity with respect to constructors, as compared with methods, is that invoking them does not involve dot notation:


    // We are invoking the Professor class's constructor method from client
    // code without using dot notation.
    Professor p = new Professor();

This is because we aren't requesting a service of a particular object, but rather are requesting that a new object be crafted from "thin air" by the programming environment; the use of the new operator emphasizes this difference syntactically. For this reason, constructors aren't considered to be methods, because as we learned earlier, methods are invoked in the context of a particular object using dot notation.

If we wish, we can explicitly program a parameterless instance constructor for our classes to do something more interesting than merely instantiating a "bare bones" object, in which case the default parameterless constructor is not automatically created for us:

public class Student
{
  // Attributes.
  private string name;
  // etc.

  // We've explicitly programmed a parameterless constructor, thus REPLACING the
  // default constructor. (Again, note that there is no return type, and that
  // the name of a constructor must match the name of the class.)
  public Student() {
    // Perhaps we wish to initialize the attribute values to something OTHER THAN
    // their zero equivalents.
    name = "?";

    // etc. -- we can do whatever makes sense in constructing a new Student:
    // creating additional objects; accessing a database; communicating with
    // other preexisting objects; whatever is required!
  }
  // Other methods omitted from this example.
}

Passing Arguments to Constructors

Constructors may also be used to pass in initial values for an object's attributes at the time that an object is being instantiated. Instead of creating an object whose attributes are all initialized to zero-equivalent values, and then utilizing the accessors provided by that class to initialize attribute values one-by-one, as illustrated by this next snippet:


    // Create a bare bones Student object.
    Student s = new Student();

    // Initialize the attributes one-by-one.
    s.Name = "Fred Schnurd";
    s.Ssn = "123-45-6789";
    s.Major = "MATH";
    // etc.

the initial values for selected attributes can all be passed in as a single step when the constructor is called, if desired:

Student s = new Student("Fred Schnurd", "123-45-6789", "MATH");

In order to accommodate this, we'd have to define a Student constructor with an appropriate header, as shown here:

public class Student {
  // Attributes.
  private string name;
  private string ssn;
  private string major;
  // etc.

  // We've programmed a constructor with three parameters to accommodate
  // passing in argument values.
  public Student(string s, string n, string m) {
    Name = n;
    Ssn = s;
    Major = m;
  }
Note?/td>

Note that we're using the Name, Ssn, and Major properties in the previous constructor to set the values of the associated name, ssn, and major attributes. As we discussed earlier in this chapter, using set accessors to set the value of attributes rather than manipulating attribute values directly allows us to make use of whatever value checking or other operations are performed inside the set accessor.

As with methods, constructor arguments can also be used to provide general "fuel" for controlling how a constructor behaves, as illustrated in the next example:


public Student(string name, bool assignDefaults) {
  Name = n;
  // Optional logic to be performed, depending on what value
  // is passed in to the assignDefaults parameter from
  // client code.
  if (assignDefaults) {
    Ssn = "?";
    Major = "undeclared";
  }
}

Constructors can be declared with any one of the five previously mentioned C# accessibility types. They are most often given public accessibility so as to enable other classes to freely instantiate objects of the constructor's type.

Note?/td>

We'll revisit constructors twice more in this book—in our discussion of over-loading in Chapter 5, and again with respect to inheritance in Chapter 13.


Team LiB
Previous Section Next Section