Reputation: 581
I was doing research on constructor overloading , below is my code
class Philosopher {
Philosopher(String s) {
System.out.print(s + " ");
}
}
public class Kant extends Philosopher {
// insert code here
Kant() {
this("Bart"); //constructor overloading
//super("Bart"); //-->can also write this
}
Kant(String s) {
super(s);
}
public static void main(String[] args) {
new Kant("Homer");
new Kant();
}
}
Now my query is that in class Kant inside it's default constructor where we are writing this("Bart"); which is making call to another constructor within class itself , can't we use super("Bart") , it will do also the same functionality, please advise.
Upvotes: 0
Views: 289
Reputation: 2778
I think this goes more after what you are looking at, which is the difference between this(...)
and super(...)
in constructor's in parent and child classes.
First, I made this comprehensive test program and ran it. I hate making claims which prove incorrect upon building...
public class Philosopher {
Philosopher(String s) {
System.out.println(s);
System.out.print("from Philosopher(String s){System.out.println(s);}... ");
}
Philosopher() {
this("whatev... ");
System.out.print("from Philosopher(){this(\"whatev... \");}... ");
}
}
class Kant extends Philosopher {
Kant(String s) {
System.out.println(s);
System.out.print("from Kant(String s){System.out.println(s);}... ");
}
Kant() {
this("whatev... ");
System.out.println("from Kant(){this(\"whatev... \");}... ");
}
Kant(int i) {
super("whatev... ");
System.out.println("from Kant(int i){super(\"whatev... \");}... ");
}
public static void main(String[] args) {
String s = "String \"s\" InMain";
System.out.print("\n\n new Philosopher(s); produces:\n");
new Philosopher(s);
System.out.print("\n\n new Philosopher(); produces:\n");
new Philosopher();
System.out.print("\n\n new Kant(s); produces:\n");
new Kant(s);
System.out.print("\n\n new Kant(); produces:\n");
new Kant();
System.out.print("\n\n new Kant(69); produces:\n");
new Kant(69);
}
}
When I run it I get this output. I am interspersing my own comments at each line of output.
new Philosopher(s);` produces
String "s" InMain
from Philosopher(String s){System.out.println(s);}...
No surprise here, call a constructor of the superclass which makes no references to this()
or super()
and it runs only the constructor of the superclass.
new Philosopher(); produces:
whatev...
from Philosopher(String s){System.out.println(s);}... from Philosopher(){this("whatev... ");}...
Not much surprise. Philosopher()
uses this("whatev...")
and the this()
refers to Philosopher(String s)
constructor. So both Philosopher()
and Philosopher(String s)
get called in this construction.
new Kant(s); produces:
whatev...
from Philosopher(String s){System.out.println(s);}... from Philosopher(){this("whatev... ");}... String "s" InMain
from Kant(String s){System.out.println(s);}...
THIS one surprised me! A simple constructor Kant(String s)
calls nothing with this()
or super()
, but it winds up visiting THREE constructors in constructing a Kant
. Every subclass constructor that doesn't explicitly call a parent class constructor will magically call the zero-argument parent-class constructor!
So any Kant
constructor that doesn't make a reference to a super
will behave just as if super();
was its first line! Thus we have construction continuity from the parent to the child.
new Kant(); produces:
whatev...
from Philosopher(String s){System.out.println(s);}... from Philosopher(){this("whatev... ");}... whatev...
from Kant(String s){System.out.println(s);}... from Kant(){this("whatev... ");}...
Kant()
has a this
in it but no super
. So Java magically behaves as though there was a super()
right in our Kant()
constructor, even though there isn't.
new Kant(69); produces:
whatev...
from Philosopher(String s){System.out.println(s);}... from Kant(int i){super("whatev... ");}...
So Kant(int i)
DOES have an explicit reference to the parent class constructor. And so its output is relatively simple, since we referred to Philosopher(String s)
directly, we don't take the extra detour through Philosopher()
that the implicit parent constructor calls gave us.
Child class constructors will ALWAYS call a parent class constructor. If you don't specify which parent class constructor to call, the zero-argument constructor will be called before any other code you have in your child class constructor. If you do specify which parent class constructor to call, you have finer control.
Constructors using this
and super
can chain together quite a bit, with up to 4 constructors being visited during an apparently simple new Kant()
object construction!
If you read all the way to this point, you deserve some kind of reward! Have a comment upvote on me...
Upvotes: 0
Reputation: 1500055
In this particular case, yes, you could just use super("Bart")
- not that in both cases this is constructor chaining. The overloading is just having multiple constructors.
Normally, however, it's a better idea to make all constructors within one class chain to a "master" constructor of that class, which is the only one with a super(...)
call. That way whatever logic you put in that constructor will be executed whichever constructor is called. In this case it's irrelevant because you don't have any other logic in the constructor, but normally that's not the case.
Upvotes: 4
Reputation: 88707
In your case you could call super("Bart")
as well.
However, consider the case where the Kant(String s)
constructor calls some additional code. In that case super("Bart")
would not execute Kant(String s)
and thus the additional code inside that constructor would not be called.
Upvotes: 0