Java inheritance fields

In java you cannot override an instance variable. The output you are getting is expected. In Java you can only override instance methods and not instance variables.

If you want 20 as an output you may use getter methods over those instance variables.

 class A {
    int i = 10;

    int getI() {
        return i;
    }
}

class B extends A {
    int i = 20;

    int getI() {
        return i;
    }
}

public class MainClass {
    public static void main(String[] args) {
        A a = new B();

        System.out.println(a.getI());
    }
}

Polymorphism is not applicable for fields in Java.Evaluating Variables decision is taken at compile time so always base class variables are accessed.


First, see Hiding Fields (emphasis added)

Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even if their types are different

In other words, this isn't "inheritance" since you're actually hiding A's i behind B's i, and you are using a reference object of A, so you are getting its fields. If you did B b = new B(), you would see 20, as expected.


If you expect true overrides, try using methods.

class A {
    public int get() { 
        return 10; 
    }
}

class B extends A {
    @Override 
    public int get() { 
        return 20; 
    }
}

See

A a = new B();
System.out.print(a.get()); // 20

If you really want to see both at once, see this example.

class A {
    int i = 10;
}

class B extends A {
    int i = 20;

    @Override 
    public String toString() { 
        return String.format("super: %d; this: %d", super.i, this.i);
    }
}

And

A a = new B();
System.out.print(a); // super: 10; this: 20