2
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

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());
Sign up to request clarification or add additional context in comments.

2 Comments

and again, why Base() constructor is calling amethod() in Derived? if you can explain
Because when you call a method on an object, it calls the method on the real type of object. So even though you are in the Base constructor, when you call amethod() it begins looking for an amethod() implementation at the child class. If it doesn't find one there, then it'll move up the inheritance hierarchy, but it always tries the child first.
2

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

2

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

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.