Java Inheritance issue
Asked Answered
P

2

14

While exploring for scjp questions, I came across this behaviour which I found strange.

I have declared two classes Item and Bolt as follows:

class Item {
    int cost = 20;

    public int getCost() {
        return cost;
    }
}

class Bolt extends Item {
    int cost = 10;

    public int getCost() {
        return cost;
    }
}

and tried to access the value of cost twice

public class Test {
    public static void main(String[] args) {
        Item obj = new Bolt();
        System.out.println(obj.cost);
        System.out.println(obj.getCost());
    }
}

The output I get is 20 10. I can't understand how this happens.

Pl answered 2/8, 2011 at 7:2 Comment(2)
No. @Override is only an indication to the compiler that you want this method to override another one, and that it should produce an error if it's not the case. But as soon as the methods have the same signature, the second one is overriding the first one. Annotations didn't exist before Java 5.Aplanospore
@netbrain, getCost method of subclass works fine. I was curious about result of directly calling obj.cost. But as Sanjay says it's due to the fact that runtime polymorphism is applicable to only methods not fields.Pl
U
19

obj is a reference of type Item hence the first 20 since the value of cost field of Item is 20. The second value is 10 because the runtime type of obj is Bolt and hence getCost() invokes getCost of Bolt class (since Bolt extends Item).

In short, runtime polymorphism is applicable to only instance members (method overriding) and not instance fields.

Unsaddle answered 2/8, 2011 at 7:5 Comment(3)
So there are two cost fields in a Bolt object?Arliearliene
From an implementation detail perspective, only one object is created when you say new Bolt(). But yes, the subclass is pretty much aware of the fields/methods its super-class hosts. You can verify this by adding a third sysout in your code: System.out.println(((Bolt)obj).cost)Unsaddle
@Sanjay, though I have not created any object of Item class, still it prints the value defined in Item class. That's what I found strange.Pl
B
7

Class fields do not participate in polymorphism game. The methods do.

So, when you access the field you go to one that is defined in base class because you object's type is Item. When you call method you get the actual value because you invoke method using polymorphism.

Conclusion:

Fields are always private. If you want to access field write method.

Blount answered 2/8, 2011 at 7:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.