Kacy Raye
Kacy Raye

Reputation: 1322

Why does the "wrong" instance variable get modified?

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

Answers (2)

Jeff
Jeff

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

Patashu
Patashu

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

Related Questions