Reputation: 1322
I'm confused because I thought this referred to the current object calling on the method.
So why didn't the instance variable x in my object not get changed when calling on an inherited method?
Superclass:
public class SuperBoss
{
int x = 50;
public void changeX()
{
this.x = 20;
}
}
Subclass:
public class Boss extends SuperBoss
{
int x = 10;
public static void main(String[] args)
{
Boss b = new Boss();
b.changeX();
System.out.println(b.x); //prints 10
}
}
Why does it print 10 and not 20?
Upvotes: 0
Views: 98
Reputation: 12795
When you declare int x = 10
in your subclass you're hiding the superclass variable from everyone when they're looking at the subclass.
When the superclass calls this.x
it's not looking at the subclass, so it's allowed to get it's own version of the variable.
Variables are not actually stored by they're code name at runtime, so redefining them like this doesn't work - SuperBoss#x
will resolve to one symbol in the symbol table and Boss#x
will resolve to another, so they both still exist, if you know how to get at them.
Upvotes: 1
Reputation: 21793
Short answer: Because field accesses are not virtual in Java.
SuperBoss declares x.
When Boss declares x, x does not become a 'virtual' field - it becomes a new field that is hidden from the superclass's field.
When you call changeX on your Boss, which is a method in SuperBoss, SuperBoss doesn't know about Boss.x and accessing x is not virtual, so it just accesses SuperBoss.x.
If you need accesses to x to be virtual, you need to provide a getX method, and override the getX method in Boss. Now when SuperBoss's methods call getX, it gets rerouted to the getX in Boss.
Upvotes: 5