Class A
calls the public method f()
in the Constructor. Class B overrides method f()
with its own implementation.
Suppose you inta
You're correct, that is the way it works. It's not recommended practice though, because somebody who inherits from your class can unintentionally break it.
When new B()
, A's Constructor is called implicitly or called via super()
. Although it is defined in Class A, actually the current class is B.
Try add the below debug info into A
's constructor and functions.
System.out.println(this.getClass());
In your case, the function f() in Class A has been overriden by Class B, so the function in A() will call B()'s implementation. However, if the f() is a private method and can not be override by B, the A.f() will be called with higher priorities.
But as others commented, it's not a good practice.
Whenever you create an instance of the subclass, the super classes constructor is invoked first (implicit super()
). So it prints
a: constructor
f()
is invoked next and since subclass overrides the superclass method, the subclass f()
is invoked. So you will see
B: f()
Now, the subclass is not initialized yet (still super() is executing) so x
default's to the value 0
because that is the default value for type int
. Because you incremented it (this.x++;
) it becomes 1
B: x = 1
Now, the superclass constructor is complete and resumes at the subclasses constructor and hence
B: constructor
The instance variables are now set to the values you have specified (against the default values that correspondt to the type (0
for numerics, false
for boolean
and null
for references))
NOTE: If you now print the value of x
on the newly created object, it will be 10
Since this is a bad practice, the static code analysis tools (PMD, FIndBugs etc) warn you if you try to do this.
I'll just provide a link, since I'm not very well-informed on the subject. See here for a tutorial that talks about the invocation order of constructors.
The most prominent quote at the end of the page related to the situation you describe is the following:
- The base-class constructor is called. This step is repeated recursively such that the root of the hierarchy is constructed first, followed by the next-derived class, etc., until the most-derived class is reached.
- Member initializers are called in the order of declaration. The body of the derived-class constructor is called.
So, as you've shown in your example, the base-class is initialised, then each of the following classes is instatiated and finally the member variables are initialised.
But as Bill as mentioned, this is not a good practice. Follow what Bill says. He has more rep than me.
EDIT: For a more complete answer, see this Jon Skeet answer. The link in this answer is broken, and only a pdf copy of the JLS can be found AFAIK. Here is a copy of the JLS in .pdf format. The relevant section is Section 8.8.7.1. There is an explanation of what the constructor invocation order is in that answer.