Overloaded Constructors and thisS2C Home « Overloaded Constructors and this

In the Constructor Basics lessons we took a first look at constructors and how to instantiate them in our classes. That isn't the end of the story though, not by a long chalk. In our second lesson on constructors we learn constructor overloading and how to use the this keyword.

Overloaded Constructors Top

Lets enhance our TestCat5 test class to call a Cat object with no arguments:


package com.server2client;
/*
  Test Class5 for Cat
*/ 
public class TestCat5 {

    public static void main (String[] args) {
        Cat moggy = new Cat("Henry", "black", 4);   // Call new Cat constructor with three arguments
        Cat tigger = new Cat("Kitty", "black", 15); // Call new Cat constructor with three arguments
        Cat tabby = new Cat("Felix", "white", 8);   // Call new Cat constructor with three arguments
        Cat tommy = new Cat();  // Call Cat constructor with no arguments
        System.out.println("Our " + moggy.colour + " cat called " + moggy.name + " is " + moggy.age);
        System.out.println("Our " + tigger.colour + " cat called " + tigger.name + " is " 
                                  + tigger.age);
        System.out.println("Our " + tabby.colour + " cat called " + tabby.name + " is " + tabby.age);
        System.out.println("Our " + tommy.colour + " cat called " + tommy.name + " is " + tommy.age);
    }
}

run cat class with no args constructor
Screenshot 1. Running the TestCat5 class.

The above screenshot shows the output of compiling our TestCat5 class. Whoa! What happened here? It has given us an error when we try to create a new Cat object using a no arguments constructor?? It appears from the error that the compiler was looking for a constructor with (String,String,int). But doesn't the compiler put in a default no arguments constructor for us? No it doesn't, as soon as we code our own constructor the compiler doesn't get involved and leaves construction to us. So if we want a default no arguments constructor as well we have to code it. Ok lets do just that:


package com.server2client;
/*
  A Cat Class
*/ 
public class Cat {
    String name, colour;
    int age;
    /*
      no-arg constructor for our Cat Class
    */ 
    public Cat() {

    }

    /*
      Below is the new constructor for our Cat Class
    */ 
    public Cat(String a, String b, int c) {
        name = a;
        colour = b;
        age = c;
    }
    
    void talk() {
  System.out.println("meow!");
    }
}

We now have two constructors in our Cat class. When a class has more than one constructor they are known as overloaded constructors. Each constructor must have different argument lists so the compiler knows which constructor to use to construct our objects. Having the same argument types is fine as long as the order differs. OK, our TestCat5 class should compile fine now, so compile and run the TestCat5 class again:

run cat class with two constructor
Screenshot 2. Rerunning the TestCat5 class.

The above screenshot shows the output of rerunning our TestCat5 class. As you can see from the output we now have a fourth line of output for a Cat object, which was instantiated using our no-arg constructor with default values.

Using the this Keyword Top

We are not finished with constructors just yet. When we call a method or constructor, it is automatically passed an implicit reference to the invoking object, or put another way, to the instance whose method or constructor is being called. As such you can refer to any member of the current object from within an instance method or constructor by using the this keyword. Ok to get our heads around this lets revamp our Cat class.


package com.server2client;
/*
  A Cat Class
*/ 
public class Cat {
    String name, colour;
    int age;
    /*
      no-arg constructor for our Cat Class
    */ 
    public Cat() {

    }

    /*
      Constructor using this Keyword
    */ 
    public Cat(String name, String colour, int age) {
        this.name = name;
        this.colour = colour;
        this.age = age;
    }
    
    void talk() {
  System.out.println("meow!");
    }
}

Run our TestCat5 class again:

using this 1
Screenshot 3. Using the this keyword.

The above screenshot shows the output of running our TestCat5 class which is exactly the same as before. We have changed the parameters to the Cat object to match our instance variables, which is a lot more meaningful than using a, b and c and used the this keyword to assign these values to the current object. This way of construction seems a lot more intuitive.

Calling this() Top

We can also invoke one constructor from another constructor within the same class using this() and doing so is known as explicit constructor invocation. If we decide to use this() it must be the first statement within our constructor or we get a compiler error. We can show an example of this using our trusty old Cat class. Lets assume for the purposes of this example that we always know a cat's colour and age but can't always be sure of a cat's name. We could pass across a string to our three argument constructor for the name such as "unknown" to cater for this. But what if someone using our Cat class didn't know of this rule and just had a cat's colour and age? How do we get around this? Well we create a two argument constructor for this purpose and do the populating of the Cat's name in there. We then call our three argument constructor from it using this(). Lets code this scenario into our Cat class.


package com.server2client;
/*
  A Cat Class
*/ 
public class Cat {
    String name, colour;
    int age;
    /*
      no-arg constructor for our Cat Class
    */ 
    public Cat() {

    }

    /*
      Our new constructor for when someone using our class doesn't know the name of a cat
    */ 
    public Cat(String colour, int age) {
        this("unknown", colour, age);
    }

    /*
      Constructor using this Keyword
    */ 
    public Cat(String name, String colour, int age) {
        this.name = name;
        this.colour = colour;
        this.age = age;
    }
    
    void talk() {
  System.out.println("meow!");
    }
}

We now need to enhance our test class to test the above changes to our Cat class out:


package com.server2client;
/*
  Test Class5 for Cat
*/ 
public class TestCat5 {

    public static void main (String[] args) {
        Cat moggy = new Cat("Henry", "black", 4);   // Call new Cat constructor with three arguments
        Cat tigger = new Cat("Kitty", "black", 15); // Call new Cat constructor with three arguments
        Cat tabby = new Cat("Felix", "white", 8);   // Call new Cat constructor with three arguments
        Cat tommy = new Cat();  // Call Cat constructor with no arguments
        Cat bobby = new Cat("beige", 6);  // Call Cat constructor with colour and age
        System.out.println("Our " + moggy.colour + " cat called " + moggy.name + " is " + moggy.age);
        System.out.println("Our " + tigger.colour + " cat called " + tigger.name + " is " 
                                  + tigger.age);
        System.out.println("Our " + tabby.colour + " cat called " + tabby.name + " is " + tabby.age);
        System.out.println("Our " + tommy.colour + " cat called " + tommy.name + " is " + tommy.age);
        System.out.println("Our " + bobby.colour + " cat called " + bobby.name + " is " + bobby.age);
    }
}

run cat class calling a constructor with this
Screenshot 4. Calling this to invoke another constructor.

The above screenshot shows the output of running our TestCat5 class. This is a much more elegant approach than calling the three argument constructor everytime with a name of "unknown". What if, down the line you decided to use "anonymous" instead of "unknown". Wherever you had called the three argument constructor in your code with a name of "unknown" you would have to change the code whereas with the constructor approach you change the code in one place.

Constructors ChecklistTop


  • A constructor runs when we code new keyword followed by a class name.
  • Constructors must have the same name as the class and no return type.
  • Constructors are used to initialize the instance variables (object state) of the object instance being constructed.
  • If you don't code a constructor in your class the compiler will put in a default no arguments constructor.
  • If you do code a constructor in your class, the compiler will NOT put in a default no arguments constructor, you will have to code it yourself.
  • We can have more than one constructor in a class and the constructors are then known as overloaded constructors.
  • When using overloaded constructors in a class, each constructor must have different argument lists so the compiler knows which constructor to use to construct our objects. Having the same argument types is fine as long as the order differs.
  • You can refer to any member of the current object from within a non-static method or constructor by using the this keyword.
  • You can invoke one constructor from another constructor within the same class by calling this() and doing so is known as explicit constructor invocation.
  • If we decide to use this() it must be the first statement within our constructor or we get a compiler error. This means we can't use this() and super() together.

This isn't the end of the story for constructors, we will look at superclass constructors when we look at OO Concepts in the next section.

Related Quiz

Objects & Classes Quiz 11 - Overloaded Constructors and this

Lesson 11 Complete

In this lesson we learnt about constructor overloading and how to use the this keyword.

What's Next?

In the next lesson we investigate what static means and how to apply it to our class members.