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.
4 Answers 4
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());
2 Comments
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.
Comments
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();
Comments
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.