Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymorphic method in Constructor (Java)

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

Suppose you intantiate Object B.. method f() of Object B would be called in the Constructor of Object A, although Object B is not fully initialized.

Can anyone explain this behavior?

EDIT: Yes, it's not recommended practice.. yet i don't understand why Java is not calling the f() implementation of the base-Class A instead of "reaching out" to the f() implementation of the derived Class B.

Code:

class A {
    A() {
        System.out.println("A: constructor");
        f();
    }

    public void f() {
        System.out.println("A: f()");
    }
}

class B extends A {
    int x = 10;
    B() {
        System.out.println("B: constructor");
    }

    @Override
    public void f() {
        System.out.println("B: f()");
        this.x++;
        System.out.println("B: x = " + x);

    }
}

public class PolyMethodConst {
    public static void main(String[] args) {
        new B();
    }
}

Output:

A: constructor
B: f()
B: x = 1
B: constructor
like image 322
lukuluku Avatar asked Feb 03 '12 02:02

lukuluku


2 Answers

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.

like image 145
Bill Avatar answered Nov 11 '22 16:11

Bill


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.

like image 29
Aravind Yarram Avatar answered Nov 11 '22 16:11

Aravind Yarram