• Post Reply Bookmark Topic Watch Topic
  • New Topic

Variable Hiding?  RSS feed

 
Tess Jacobs
Ranch Hand
Posts: 71
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the code below, I expect the inherited getX() method in class B to return In class B. Why does it return In class A?



In the code below, the inherited getX() method in class B behaves as expected and returns In class B. How is this code different from the previous code?

 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because variables don't get overridden. Only non-static, non-final, non-private methods do. So in A's getX() method, the x variable refers to A's x.
 
Campbell Ritchie
Marshal
Posts: 56527
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That is why it is a bad idea to have fields with the same name in the superclass and the subclass.
 
Paul Witten
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tess Jacobs wrote:In the code below, I expect the inherited getX() method in class B to return In class B. Why does it return In class A?

Another angle for you Tess: In example 1 there is only one getX() method, right? So if you invoke it there are no choices - it's going to run that method which is in class A. The string you declared in class B has nothing to do with invoking a getter method.

But in example 2 you are demonstrating how the local (class B) getX() overrides the class A getX(). That's what you get (override) when you name a subclass method the same as a superclass method.

Debugging/analyzing is not a big deal when you know for a fact that you are overriding a superclass method. In such a case you just ignore the superclass method in your analysis. If you didn't realize you had overridden a superclass method then you are set up for a confusing analysis.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Witten wrote:
Tess Jacobs wrote:In the code below, I expect the inherited getX() method in class B to return In class B. Why does it return In class A?

Another angle for you Tess: In example 1 there is only one getX() method, right? So if you invoke it there are no choices - it's going to run that method which is in class A.


That's a bit of a red herring actually. Even with only one getX() method, if the body of getX() called a method x() (instead of accessing a variable x), and if that method were overridden in a subclass, we'd invoke the subclass's version of x(). So it's not a leap to think that if we access a variable x, and that variable is overridden in the subclass, we should be referring to the subclass's variable x. And in fact, I wouldn't be surprised if some languages work that way.

The key to why it doesn't work that way in Java is that variables cannot be overridden, only hidden. This means that it is determined at compile time, by the type of the reference, which class's x variable will be used. In fact the only thing that can be overridden--the only decision made at runtime based on the class of the object and not the type of the reference--is which class's version of a particular signature of a non-static, non-private, non-final method will be called. (And note that the exact signature is itself determined at compile time--which is the source of another common confusion among beginners.)
 
Paul Witten
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote:
Paul Witten wrote:
Tess Jacobs wrote:In the code below, I expect the inherited getX() method in class B to return In class B. Why does it return In class A?

Another angle for you Tess: In example 1 there is only one getX() method, right? So if you invoke it there are no choices - it's going to run that method which is in class A.


That's a bit of a red herring actually. Even with only one getX() method, if the body of getX() called a method x() (instead of accessing a variable x), and if that method were overridden in a subclass, we'd invoke the subclass's version of x().

That is SICK! Haha, in a good kind of way. Beware all those who pass through that portal of pain unwittingly.

That's a smart compiler there. It actually follows the chain of calls to find subclass methods named the same as what is called by a getter in the superclass? Sick, man. But it's a good sick.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Witten wrote:
That's a smart compiler there. It actually follows the chain of calls to find subclass methods named the same as what is called by a getter in the superclass? Sick, man. But it's a good sick.


No, the complier doesn't decide to use the subclass's method. The compiler doesn't know whose version of the method gets called. It's the runtime that determines that. That's what overriding is all about.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!