I'm a beginner and currently reading inheritance and polymorphism. I'm having some confusion in terms of the keyword "extend" and how constructors are called. Here's the code:
public class Test {
public static void main(String[] args) {
new B();
}
}
class A {
int i = 7;
public A() {
System.out.println("i from A is " + i);
}
public void setI(int i) {
this.i = 2 * i;
}
}
class B extends A {
public B() {
setI(20);
System.out.println("i from B is " + i);
}
public void setI(int i) {
this.i = 3 * i;
}
}
I know that by calling B() in line 3, class A's constructor is invoked, and then B's is invoked (is that right?) and thus it displays "i from A is 7" and then "i from B is 60". But can someone explain the importance of this? Why is int i in B completely different from in i in A? Again, I'm having trouble following the "path" of the code after the line new B(). If someone could explain each step after B() is invoked, that would be much appreciated.
I'm having trouble following the "path" of the code after the line new B(). If someone could explain each step after B() is invoked, that would be much appreciated.
When calling new B()
, the flow technically enters the constructor B()
first. Constructors in Java always need to (eventually) chain to a higher constructor (recursively until the highest class, Object
, is reached). Chaining is denoted by a super(...)
or this(...)
statement as the first statement of the constructor. If none is explicitly written, the parameterless super()
is assumed. So, B()
actually compiles as if it were written like this:
public B() {
super();
setI(20);
System.out.println("i from B is " + i);
}
Now you can clearly see that new B()
calls B()
which calls A()
(which calls println
and exits), then setI
and finally println
.
Why is int i in B completely different from in i in A?
The i
is exactly the same field. The difference comes from the fact that you've invoked setI(20)
between the two printouts, thus changing the value of i
. If you remove the call to setI
, you'll see that the value remains 7
.
When you are creating your instance of B and you call the constructor B(), it will first call super()
, which in your case will call A()
.
This prints i from A is 7
, because 7 is your default that you are setting i
to.
After super is called, it moves on to the next line, which is setI(20)
. This line sets the i
in B to 60 because your setI(int i)
method multiplies the parameter (20) by 3, then sets i
to that value.
Then, you are printing i from B is 60
because i
is now 60.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With