A class can have multiple constructors, this is known as constructor overloading. It is a feature of polymorphism. Constructor overloading is a very useful feature. It fact, it is similar to method overloading.
Java differentiates constructors using constructor signatures. A constructor signature is a part of constructor declaration. It is the combination of the constructor name, which is the class name it lives in, and the parameter list. The names of the parameters are not included in the signature.
In order to overload a constructor, the constructor signatures should be different. Which means your constructors need to have different parameter lists. When the
When you invoke an overloaded constructor, Java uses the following conditions to determine which version of the overloaded constructor you are calling. * The type of each argument you are passing. * The number of arguments you are passing.
This is the reason why overloaded constructors must have different parameter lists. Otherwise, Java won’t be able to determine which version of the overloaded constructor you are calling. It goes without saying, no two constructors in a class can have the same number and type of arguments, because this is the only way constructors can be differentiated.
Consider the following class.
public class Movie {
private String title;
private float ratings;
private float runtime;
public Movie(String title) {
this.title = title;
}
public Movie(String title, float ratings) {
this.title = title;
this.ratings = ratings;
}
public Movie(String title, float ratings, float runtime) {
this.title = title;
this.ratings = ratings;
this.runtime = runtime;
}
@Override
public String toString() {
return "title: " + title + ", ratings = " + ratings + ", runtime = " + runtime;
}
}
In this example, we defined three constructors.
The first constructor accepts a String
parameter named title
. It initializes
corresponding title
field.
The second constructor accepts two paramters named title
and ratings
of
the type String
and float
, respectively. It initializes the fields with
the corresponding values.
The third constructor accepts three paramters named title
, ratings
, and
runtime
of the type String
, float
, and float
, respectively. It initializes
the fields with the corresponding values.
You can create an instance of Movie
like this.
Movie movie = new Movie("Forrest Gump", 8.8f, 2.22f);
A constructor can call another constructor in the same class. Java provides
special syntax for this purpose. You must use this
the keyword with parenthesis.
This is useful when your overloaded constructors have some common behavior of an
existing constructor. You can call the general purpose constructor from your
other constructors.
Here is an example of Movie
class where the constructors invoke another
general purpose constructor.
public class Movie {
private String title;
private float ratings;
private float runtime;
public Movie() {
this("Unknown", 0.0f, 0.0f);
}
public Movie(String title) {
this(title, 0.0f, 0.0f);
}
public Movie(String title, float ratings) {
this(title, ratings, 0.0f);
}
public Movie(String title, float ratings, float runtime) {
this.title = title;
this.ratings = ratings;
this.runtime = runtime;
}
}
In the above example, we declared four constructors.
The first constructor is the explicit default constructor. It accepts no parameters. It passes default values to the fourth constructor, which is general purpose constructor.
The second constructor accepts the title of a movie. It passes the title and default values to the third constructor.
The third constructor accepts the title and ratings of a movie. It initializes the corresponding fields.
The fourth constructor, the general purpose constructor which is invoked by
all the other constructors, accepts three parameters length
, ratings
and runtime
. It initializes the corresponding fields.
You need to follow these rules when calling another constructor.
For example, this will not compile.
public Movie(String title) {
int i = 0;
this(title, 0.0f, 0.0f);
}
You can call another constructor only in the first statement. But in the above example, a declaration statement is the first statement. This results in a compile-time error.
For example, this will not compile.
public class Movie {
private String title;
private float ratings;
private float runtime;
public Movie() {
this("Unknown", 0.0f, 0.0f);
}
public Movie(String title) {
this();
this(title, 0.0f, 0.0f);
}
public Movie(String title, float ratings) {
this(title, ratings, 0.0f);
}
public Movie(String title, float ratings, float runtime) {
this.title = title;
this.ratings = ratings;
this.runtime = runtime;
}
}
You can call only one constructor. But in this example, the second constructor invokes two constructors. This results in a compile-time error.
For example, the first constructor can call the second constructor. The second constructor can call the third constructor.
public class Person {
private String name;
private int age;
private String number;
public Person() {
this("Unknown");
}
public Person(String name) {
this(name, -1, "Unknown");
}
public Person(String name, int age, String number) {
this.name = name;
this.age = age;
this.number = number;
}
}
For example, the first constructor calls the second constructor. The second constructor calls back the first constructor. Such cases will generate errors.
public class Pet {
private String name;
private String species;
private String owner;
private int age;
public Pet() {
this("Unknown", "Unknown", "Unknown", -1);
}
public Pet(String name, String species, String owner, int age) {
this();
this.name = name;
this.species = species;
this.owner = owner;
this.age = age;
}
}