Polymorphic method in Constructor (Java)

独自空忆成欢 提交于 2019-11-29 01:52:42

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.

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.

blahman

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:

  1. 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.
  2. 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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!