views:

135

answers:

2
abstract class AbstractBase {
    abstract void print();

    AbstractBase() {
        // Note that this call will get mapped to the most derived class's method
        print();
    }
}

class DerivedClass extends AbstractBase {
    int value = 1;

    @Override
    void print() {
        System.out.println("Value in DerivedClass: " + value);
    }   
}

class Derived1 extends DerivedClass {
    int value = 10;

    @Override
    void print() {
        System.out.println("Value in Derived1: " + value);
    }
}

public class ConstructorCallingAbstract {

    public static void main(String[] args) {
        Derived1 derived1 = new Derived1();
        derived1.print();
    }
}

The above program produces the following output:

Value in Derived1: 0
Value in Derived1: 10

I am not getting why the print() in AbstractBase constructor always gets mapped to the most derived's class (here Derived1) print()

Why not to DerivedClass's print() ? Can someone help me in understanding this?

+9  A: 

Because all Java method invocations that are not explicitly super invocations are dispatched to the most derived class, even in superclass constructors. This means that superclasses get the benefit of subclass behaviors, but it also means that overriding methods can theoretically get invoked before the constructor in that class.

John Calsbeek
John do you have some reference where this behavior is explained explicitly (somewhere in java specs. etc)
peakit
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.12.4.4
starblue
+2  A: 

Virtualization in Super Class Constructor.

Take a look at http://stackoverflow.com/questions/308061/virtualization-in-super-class-constructor

adatapost