Reputation: 20078
class Base
{
int i = 99;
public void amethod()
{
System.out.println("Base.amethod()");
}
Base()
{
amethod();
}
}
public class Derived extends Base
{
int i = -1;
public static void main(String argv[])
{
Base b = new Derived();
System.out.println(b.i);
b.amethod();
}
public void amethod()
{
System.out.println("Derived.amethod()");
}
}
Why does this code print b.i = 99
and not b.i = -1
?
Thank you.
Upvotes: 2
Views: 783
Reputation: 40276
Because in this instance b.i is saying ((Base).i) meaning it will reference the Base's i variable and not the Derived i. If instead you did b.getI()
and each Base and Dervid implemented their own getI and returned their own i it would return -1.
To explain why Base is calling Derived's amethod. Java method invocation is dynamic and determined at runtime. In your case Base b = new Derived()
b here is of type Derived. The Java runtime will realize b's type and invoke the amethod created closest to Derived.
So if you have
class Base{
int i =99;
public int getI(){
return i;
}
}
class Derived extends Base{
int i =-1;
public int getI(){
return i;
}
}
Derived's getI() method will be called (and return -1) even if its defined as Base b = new Derived();
Upvotes: 2
Reputation: 21890
It's because you are referencing a member variable of the object instead of a method. Since it is declared as a Base object, it will use Base.i because member variables do not benefit from polymorphism that is afforded to methods. If you added a getI() method to both classes and called that instead of just b.i, it would work as you expect.
public int getI() {
return this.i;
}
Base b = new Derived();
System.out.println(b.getI());
Upvotes: 4
Reputation: 120586
Methods can be overridden, but fields mask, so your subclass defines a new field named i
. The superclass methods refer to the old field i
defined in the superclass.
Upvotes: 1
Reputation: 888273
You have two different fields named i
; one in Base
and one in Derived
.
Since b
is declared as a Base
, b.i
returns the i
field from the Base
class.
You probably want to set the i
field in the Derived
constructor instead of creating a new field.
Upvotes: 2