10

In the following example:

class Base {    
    int  x=10;  

    Base() {    
      show();
    }  

    void show() {   
        System.out.print ("Base Show " +x + "  ");
    }  
}  

class Child extends Base {   
    int x=20;  

    Child() {
        show();
    }  

    void show() {    
        System.out.print("Child Show " + x +"  ") ; 
    }  

    public static void main( String s[ ] ) {   
        Base obj = new Child();   
    }  
} 
  • Why is the output as shown below
Child Show 0  Child Show 20
  • I thought constructors can only access instance members once its super constructors have completed.

I think what is happening here is that the super constructor is calling the child's show() method because this method was overridden in Child. as it has been overridden but why is the value of x 0 and why is it able to access this method before the super constructor has completed?

Cœur
  • 37,241
  • 25
  • 195
  • 267
ziggy
  • 15,677
  • 67
  • 194
  • 287
  • Is virtual handling mechanism enabled during construction of an object ? I doubt it isn't. – Mahesh Dec 09 '11 at 18:48
  • In C++ this can cause a crash. – Luchian Grigore Dec 09 '11 at 18:50
  • 3
    Effective Java is a great Java resource and it goes into this in great detail. From Item 17: "***Constructors must not invoke overridable methods**, directly or indirectly (...) If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected. ...*" If you have the book on hand I highly recommend reading this Item. – Mark Peters Dec 09 '11 at 18:55

4 Answers4

12

I think what is happening here is that the super constructor is calling the child's show() method because this method was overriden in Child.

That is correct

but why is the value of x 0

because it's not initialized yet (x of Child)

and why is it able to access this method before the super constructor has completed?

That's exactly why in a constructor you should never call a method, which can be overridden (non-final public and protected).

Edit:

The strange thing here is that everything has default/ package-private visibility. This can have some strange effects. See: http://www.cooljeff.co.uk/2009/05/03/the-subtleties-of-overriding-package-private-methods/

I recommend to avoid overriding methods with default visibility if possible (you can prevent this by declaring them final).

Puce
  • 37,247
  • 13
  • 80
  • 152
  • 1
    +1 The sequence is main -> Child() -> Base() -> Child.show() [x not yet initialized] -> Base.show() [preceded by Base.x = 20] – stacker Dec 09 '11 at 18:59
  • 1
    No, the sequence is main -> Base() -> Child.show() [x not yet initialized] -> Child() [Child.x = 20] -> Child.show() – Puce Dec 09 '11 at 19:30
  • does the variable x on the Child class has been given a default value of 0 when the Object class has been completed? Because as far as I can remember here is the sequence : new Child() -> Base() -> Object -> Child's implementation of show() ... – anathema Jun 23 '15 at 02:51
  • @anathema The Object class does not define any fields. But AFAIK, the default value is set during memory allocation, so something like: main -> Child memory allocation on heap with default values -> Object() -> Base() -> Child.show() [x not yet initialized] -> Child() [Child.x = 20] -> Child.show() – Puce Jun 23 '15 at 08:09
6

You can call overriden methods from constructors, but it's bad and you shouldn't. You illustrated the reason why this is bad: the derived class doesn't get a chance to get initialized, so uninitialized fields will be used - in your example, the default for int x is 0, that's why it's printing 0.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
2

constructor chaining it makes sense to explain exactly what that is. A subclass constructor method's first task is to call its superclass' constructor method. This ensures that the creation of the subclass object starts with the initialization of the classes above it in the inheritance chain.

http://java.about.com/b/2009/02/07/java-term-of-the-week-constructor-chaining.htm

http://javahours.blogspot.com/2008/12/constructor-chain.html

Noufal Panolan
  • 1,357
  • 2
  • 14
  • 27
1

Childs override of the show method is invoked because that's what the Java spec calls for. Here is a great discussion of why you should not do it. The value of x is zero because Child has not finished initializing yet.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523