Adrian
Adrian

Reputation: 20078

Java code explanation

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

Answers (4)

John Vint
John Vint

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

Kenny Wyland
Kenny Wyland

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

Mike Samuel
Mike Samuel

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

SLaks
SLaks

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

Related Questions