Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling an overridden method from a constructor

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?

like image 651
ziggy Avatar asked Dec 09 '11 18:12

ziggy


People also ask

Can you call an overridden method?

But, since you have overridden the parent method how can you still call it? You can use super. method() to force the parent's method to be called.

Is it OK to call methods in constructor?

Yes, as mentioned we can call all the members of a class (methods, variables, and constructors) from instance methods or, constructors.

Is method overriding is possible in constructor?

Constructor looks like method but it is not. It does not have a return type and its name is same as the class name. But, a constructor cannot be overridden.

Can we override already overridden method?

You cannot override a non-virtual or static method. The overridden base method must be virtual , abstract , or override . An override declaration cannot change the accessibility of the virtual method. Both the override method and the virtual method must have the same access level modifier.


2 Answers

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).

like image 53
Puce Avatar answered Oct 23 '22 10:10

Puce


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.

like image 20
Luchian Grigore Avatar answered Oct 23 '22 10:10

Luchian Grigore