Java Inheritance Output Question

Java Inheritance Output Question: Variable Shadowing with int i (2026)

What is the output of the below program?

class A {
    int i = 10;
    void get() {
        System.out.println(i);
    }
}

class B extends A {
    int i = 100;
    void get() {
        System.out.println(i);
    }
    public static void main(String h[]) {
        B a = new B();
        a.get();
    }
}

Before you scroll down, pick your answer:

  1. 10
  2. 100
  3. Compile error
  4. None

The correct answer is: 2. 100

The program compiles and prints 100. Here is exactly why.

Step 1: The object type is B

B a = new B(); creates an object of class B. The reference variable a points to a B object.

Step 2: Method overriding picks B's get()

Class B overrides get(). When you call a.get(), Java looks at the actual object type (B) and runs B's version of get(), not A's.

Step 3: Inside B.get(), i refers to B's field

Class B declares its own int i = 100. This field shadows the i in class A. Inside B.get(), the name i resolves to the closest visible declaration, which is B's i = 100.

So System.out.println(i) prints 100.

Final output: 100

Why this question is a classic trap

Two features of Java collide here:

  • Method overriding — B.get() overrides A.get(). The runtime picks the most specific version based on the object type.
  • Variable shadowing — B.i hides A.i. Field access is resolved at compile time based on the reference type and the enclosing class, not the runtime type.

Most developers assume A's i will be used because get() looks like it belongs to the same class hierarchy. It does belong to the hierarchy, but the i inside B.get() means "the i visible in B," and that is B's i.

The rule to remember

Concept Resolved By What Wins
Method overriding Runtime object type Most specific override (B.get())
Field access (shadowing) Compile-time reference type and enclosing class The field in the current class (B.i)

Why fields do not override: In Java, fields are not polymorphic. Unlike methods, a field is bound to the reference type at compile time. B.i and A.i are two separate variables occupying the same object's memory. When you write i inside B, the compiler resolves it to B.i.

How to print A's i from B

If you want to see 10 instead, you have to access the parent's field explicitly using super:

class B extends A {
    int i = 100;
    void get() {
        System.out.println(i);        // prints 100 (B's i)
        System.out.println(super.i);  // prints 10  (A's i)
    }
}

Output:

100
10

super.i tells the compiler: "do not look in B, look one level up." That is the only way to reach the shadowed field from inside the subclass.

Common variations interviewers ask next

Variation Output Why
A a = new B(); then a.get(); 100 Method overriding still picks B.get(). The runtime object is B.
A a = new B(); then System.out.println(a.i); 10 Field access uses the reference type. a is declared as A, so A.i is used.
Remove get() from B 10 B inherits A.get(), and i inside it resolves to A.i.
Make i in both classes private 100 Shadowing still occurs. Private only restricts external access, not the internal name resolution.

Where to go next

You now know the answer is 100, you know why, and you know the difference between method overriding and field shadowing.

The rule to remember: methods override, fields hide. Java picks the method based on the runtime object. It picks the field based on the class where the code is written.

If you want to go deeper, try adding super.i to B.get() and run it again. Watch both values print. Then try changing the reference type in main to A a = new B(); and see what a.i gives you. The answer will surprise anyone who thinks fields behave like methods.

No comments: