Polymorphic method in Constructor (Java)

前端 未结 4 2063
温柔的废话
温柔的废话 2021-02-08 09:46

Class A calls the public method f() in the Constructor. Class B overrides method f() with its own implementation.

Suppose you inta

相关标签:
4条回答
  • 2021-02-08 09:49

    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.

    0 讨论(0)
  • 2021-02-08 10:06

    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.

    0 讨论(0)
  • 2021-02-08 10:08

    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.

    0 讨论(0)
  • 2021-02-08 10:10

    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.

    0 讨论(0)
提交回复
热议问题