Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method overriding and Inheritance in java

Consider the following code segment:

class A{ /* assume static and non static block are here */ }
class B extends A{ /* assume static and non static block are here */ }

In main method,

 new B();

So the order of the initialization would be :

  1. static members initialization for class A
  2. static members initialization for class B
  3. non static members initialization for class A
  4. then execute the code inside constructor A
  5. non static members initialization for class B
  6. then execute the code inside constructor B

Now take a look at this code segment,

class A{
    A(){
        this.m(); //line 1
    }

    void m(){
        System.out.println("A.m()");
    }
  }

  class B extends A{
     void m(){
        System.out.println("B.m()");
    }
  }

In main method,

 new B();

When the code of constructor A is being executed, it can only see the method m in class A since non static members hasn't been initialized yet for class B (according to the order I mentioned). However the result is "B.m()". (method of sub class has been executed) Can someone explain what is happening here(method overridng) considering the order that I have mentioned ?

like image 471
chathura Avatar asked Aug 12 '13 15:08

chathura


2 Answers

When the code of constructor A is being executed, it can only see the method m in class A since non static members hasn't been initialized yet for class B (according to the order I mentioned).

You're assuming that methods are part of "non-static members" which are initialized. That's not the case - it's really a matter of fields in B being initialized when the A constructor is finished.

As soon as an object is created in Java, its type is set and never changes. Enough space is allocated for all the fields - but the fields are actually initialized from the top of the inheritance hierarchy down.

So yes, if you call an overridden method from a constructor, it will execute in a context where some of the fields it wants to use aren't initialized - so you should avoid doing that if possible.

like image 149
Jon Skeet Avatar answered Oct 18 '22 18:10

Jon Skeet


Method overriding happens whether or not the derived class has been initialized.

This is why you should avoid calling virtual methods in initializers.

like image 3
SLaks Avatar answered Oct 18 '22 18:10

SLaks