next up previous contents
Next: Java Interlude 1 Quick Up: Data encapsulation with classes Previous: Constants (the attribute final)   Contents

Constructors

When we create an object using new, we get an uninitialized object. We then have to set the values of the instance variables to sensible values (almost always this has to be done via appropriate methods, because these variables will be private). It is natural to ask for the analogue of a declaration of the form:

    int i = 10;

which ``creates'' a variable i of type int and also, simultaneously, sets its initial state.

In the object-oriented paradigm, this initialization is performed by special methods, called constructors. A constructor is a method that is called implicitly when the object is created. It cannot be called after the object has been created.

In Java, a constructor is written as a public method with no return value which takes the same name as the class. For example, we can define a class Date as follows:

  class Date{

    private int day, month, year;

    public Date(int d, int m, int y){
      day = d;
      month = m;
      year = y;
    }

  }

Now, if we write

  Date d = new Date(27,1,2003);

d points to a new Date object whose values are initialized with day = 27, month = 1 and year = 2003.

We may want to have more than one way to construct an object. If no year is supplied, we might set the field year to the current year, by default.

We can add a second constructor as follows:

    public Date(int d, int m)
      day = d;
      month = m;
      year = 2003;
    }

Now, if we write

  Date d1 = new Date(27,1,2002);
  Date d2 = new Date(27,1);

d1 calls the first constructor, as before, while d2 calls the second constructor (where year is set to 2003 by default).

This ability to have multiple constructors with different ``signatures'' extends to methods as well. In Java, the signature of a method is its name plus the types of its arguments. One can overload method names just like we have overloaded the constructors above. In fact, in the Java built-in class Arrays, there is a static method sort that sorts arbitrary arrays of scalars. In other words, we can write:

  double[] darr = new double[100];
  int[] iarr = new int[500];
  ...
  Arrays.sort(darr);  // sorts contents of darr
  Arrays.sort(iarr);  // sorts contents of iarr

This is done by defining, within the class Arrays, multiple methods named sort with different signatures, as follows:

  class Arrays{
    ...
    public static void sort(double[] a){  // sorts arrays of double[]
      ...
    }
    public static void sort(int[] a){  // sorts arrays of int[]
      ...
    }
    ...
  }

When we invoke Arrays.sort with an argument a, the type of a automatically determines which version of the overloaded method sort is used.

Coming back to constructors, what happens if we have no constructors defined? In this case, Java provides a ``default'' constructor that takes no arguments and sets all instance variables to some sensible defaults (e.g., an int is set to 0). Suppose we have a class as follows:

  class no_constructor{
    private int i;

    // some methods below
    ...
  }

We would then write something like:

  no_constructor n = new no_constructor(); // Note the () after
                                           // the class name

However, if there is at least one constructor defined in the class, the default constructor is withdrawn. So, if we have the class Date as given above, it is an error to write:

  Date d = new Date();

If we want this to work, we must explicitly add a new constructor that has no arguments.

Remember that it is not possible to invoke a constructor later. Though Date(int,int,int) is a public ``method'' in the class, it has a different interpretation. We cannot say;

  Date d = new Date(27,1,2003);
  ...
  d.Date(27,1,2003);

One constructor can call another, using the word this. We can rewrite the two constructors in the class Date as follows:

  class Date{

    private int day, month, year;

    public Date(int d, int m, int y){
      day = d;
      month = m;
      year = y;
    }

    public Date(int d, int m){
      this(d,m,2003);
    }

  }

The second constructor invokes the first one by supplying a fixed third argument. In Java, such an invocation using this must be the first statement in the constructor. We can reverse the constructors as follows:

  class Date{

    private int day, month, year;

    public Date(int d, int m){
      day = d;
      month = m;
      year = 2003;
    }

    public Date(int d, int m, int y){
      this(d,m);   // this sets year to 2003
      year = y;    // reset year to the value supplied
    }

  }


next up previous contents
Next: Java Interlude 1 Quick Up: Data encapsulation with classes Previous: Constants (the attribute final)   Contents
Madhavan Mukund 2004-04-29