Java - Constructor chaining
Don't let constructors repeat themselves!
Let's say we have a Person
class that has three properties: lastName
, firstName
and socialSecurityNo
. And let's say we can instantiate a Person
either:
- with one argument:
socialSecurityNo
(which will setfirstName
andlastName
to an empty string) - with two arguments:
firstName
andlastName
(which will set thesocialSecurityNo
to an empty string) - with all three arguments
public class Person {
private static final String EMPTY_STRING = "";
private String lastName;
private String firstName;
private String socialSecurityNo;
public Person(String socialSecurityNo) {
this.firstName = EMPTY_STRING;
this.lastName = EMPTY_STRING;
this.socialSecurityNo = socialSecurityNo;
}
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
this.socialSecurityNo = EMPTY_STRING;
}
public Person(String firstName, String lastName, String socialSecurityNo) {
this.firstName = firstName;
this.lastName = lastName;
this.socialSecurityNo = socialSecurityNo;
}
}
This approach works, but it's not the cleanest one as it relies a lot on code duplication.
A better way of implementing the same thing would be for constructors to use one another so we won't duplicate code anymore.
public Person(String socialSecurityNo) {
this(EMPTY_STRING, EMPTY_STRING, socialSecurityNo);
}
public Person(String firstName, String lastName) {
this(firstName, lastName, EMPTY_STRING);
}
public Person(String firstName, String lastName, String socialSecurityNo) {
this.firstName = firstName;
this.lastName = lastName;
this.socialSecurityNo = socialSecurityNo;
}
The call to this()
can only be called inside a constructor and can only be the first statement.
Bonus
Let's say we have a Student
class, with one property: classroom
, that extends the Person
.
public class Student extends Person {
private static final String EMPTY_STRING = "";
private String classroom;
public Student(String socialSecurityNo, String classroom) {
super(socialSecurityNo);
this.classroom = classroom;
}
public Student(String firstName, String lastName, String classroom) {
super(firstName, lastName);
this.classroom = classroom;
}
public Student(String firstName, String lastName, String socialSecurityNo, String classroom) {
super(firstName, lastName, socialSecurityNo);
this.classroom = classroom;
}
}
The call tosuper()
, as the call tothis()
, can only be called inside a constructor and should only be the first statement.
Again, we have a lot of code duplication.
In order to be able to call the super()
constructor and this()
call to be able to use the constructor chaining we should do it this way:
public class Student extends Person {
private static final String EMPTY_STRING = "";
private String classroom;
public Student(String socialSecurityNo, String classroom) {
this(EMPTY_STRING, EMPTY_STRING, socialSecurityNo, classroom);
}
public Student(String firstName, String lastName, String classroom) {
this(firstName, lastName, EMPTY_STRING, classroom);
}
public Student(String firstName, String lastName, String socialSecurityNo, String classroom) {
super(firstName, lastName, socialSecurityNo);
this.classroom = classroom;
}
}
The call to super()
is made by only one constructor, that the others refer to.
Stay tuned! 🚀