Reputation: 1787
Just started learning java recently, and in my textbook I came across this
which was very confusing at first but now its starting to make sense. Now, in my book we
started basic applications of constructors and as a side note on the page it said this
, can also be used to call other constructors. I was a bit confused, then
look at other questions on SO regarding this
. I think I get it to an extent now, but WHY would I ever want to do this? Consider the following which I just made up.
private double balance;
private double interest;
public Account(double initialBalance){
balance = initialBalance;
}
public Account(double balance, double interest){
this(0);
balance = initialBalance;
this.interest = interest;
}
Here this(0);
, to my understanding looks for another constructor with one parameter, finds Account(double initialBalance)
, and sets initialBalance
to zero.
Great. Erm, but why wouldn't I just do that directly? Just set balance equal to zero! I am sure it is very useful but I can't think of any examples.
Thanks!
Upvotes: 1
Views: 144
Reputation: 109547
That example does indeed make not much sense.
The following does.
private double balance;
private double interest;
public Account(double initialBalance){
this(initialBalance, 9.99);
}
public Account(double balance, double interest){
this.balance = balance;
this.interest = interest;
}
And indeed one calls another constructor, that typically does some work than just assigning.
For the original example it could be that the simple constructor was made first, and later the constructor with the extra argument was added for an extra field interest
.
So one might see this construct often, and it is comparable with calls to super(...)
Also in simple cases, this usage follows the DRY principle: Don't Repeat Yourself. Mind if one of the constructor had just a bit different couple of assignments in time, the program would become constructor case dependent. Now you know, that the same code is walked through, and you do not have to test that functionality N times.
Upvotes: 1
Reputation: 1263
Overloading constructors may come in handy many times. One example is when you have multiple arguments but not all of the are mandatory.
Using overloading you can do something like:
public Account(string id, double balance, string name, strings address){
this.id = id;
this.balance = balance;
this.name = name;
this.address = address;
}
public Account(string id, double balance, string name){
this(id, balance, name, null);
}
public Account(string id, double balance){
this(id, balance, "Unknown" ,null);
}
public Account(string id){
this(id, 0, "Unknown" ,null);
}
Upvotes: 1
Reputation: 590
The example from Java documentation will probably make much more sense than the one you have at your hands:
public class Rectangle {
private int x, y;
private int width, height;
public Rectangle() {
this(0, 0, 1, 1);
}
public Rectangle(int width, int height) {
this(0, 0, width, height);
}
public Rectangle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
...
}
Upvotes: 3
Reputation: 15706
It's very practical and avoids code duplication:
public Account(){
this(0);
}
public Account(double initialBalance){
this(initialBalance, DEFAULT_INTEREST_RATE);
}
public Account(double balance, double interest){
balance = initialBalance;
this.interest = interest;
}
The constructors with less arguments delegate to constructors with more arguments, passing defaults for the absent arguments.
If this weren't possible, one would need an artificial init(..)
method which accepts the parameters, and is called from all constrcutors. This is less secure, as this method could be called repeatedly.
Upvotes: 5
Reputation: 1088
Here's a good example to use another constructor of the same Object:
public Person(String name, String street, String location) {
(...)
//handle them
}
public Person() {
this("default name", "default street", "default location");
}
It's basically a shortcut (Overloading), so you stay clear of redundant code.
Upvotes: 1
Reputation: 1207
It would make more sense if you put it the other way around.
public Account(double initialBalance){
this(initialBalance, 2.0); // 2.0 being a default interest (whatever you'd like, could be 0).
}
public Account(double balance, double interest){
this.balance = balance;
this.interest = interest;
// Some more very difficult business logic
}
This way you can prevent duplicate code. A change in the difficult business logic would only have to be changed once (if needed).
Upvotes: 0
Reputation: 91017
Think about that you could do it the other way: Your "basic" constructor is
public Account(double balance, double interest){
balance = initialBalance;
this.interest = interest;
}
and based on this, you could add some simplifications:
public Account(double initialBalance){
this(initialBalance, DEFAULT_INTEREST);
}
public Account(){
this(DEFAULT_INITIAL_BALANCE, DEFAULT_INTEREST);
}
Calling these constructors simplifies changing the principal behaviour: if I, e. g., want to register the new object somewhere, I can do so at one central place and have the other constructors rely on that.
Upvotes: 1
Reputation: 3164
This is called "constructor overloading". Just like method overloading, this is Java's way of allowing you to supply different amounts of parameters for a single method.
It is generally used for methods, or in this case, constructors that have "optional" parameters. Heres an example that should make it more obvious:
class Cat{
private int paws;
private String name;
public Cat(String name){
//Assume that the cat is physically not handicapped, and thus has 4 paws
this(name,4);
}
public Cat(String name, int paws){
this.name = name;
this.paws = paws;
}
}
Upvotes: 0