Reputation: 572
I thought I understood the concept of shadowing. But this Code made me wonder:
public class Counter {
int count = 0;
public void inc() {
count++;
}
public int getCount() {
return count;
}
}
class StepCounter extends Counter {
int count = 0;
int step = 1;
public StepCounter(int step) {
this.step = step;
}
public void inc() {
count += step;
}
}
StepCounter sc = new StepCounter(2);
sc.inc();
sc.inc();
System.out.println(sc.getCount());
System.out.println(sc.count);
So basically the Static Type of sc is StepCounter
.
It's counter is incremented twice, so it's at 4 after the first two commands.
My count Variable is not a private one, it is package private (since I haven't declared any visibility on it).
So if I call the .getCount()
method on sc, it first looks for it in StepCounter. There is none, so it goes to Counter. Here it finds the getCount()
method.
that method returns count. If count had been static or private, I'd understand why it returns 0. But why does it return 0 in this case? Even if I made the variable count public in StepCounter
, the result would still be 0.
Upvotes: 1
Views: 130
Reputation: 77495
getCount()
can only access the field counter
tht was defined in the parent class. This class is resolved at compile time of the parent class. There is no copy of the method getCounter()
in the child.
In the child class, you can use
Counter.this.count
to access the parent counter. But to avoid bad surprises, you should never name a field in such a ambiguous way.
Upvotes: 2
Reputation: 103
You should always avoid shadowing as much as possible, it could introduce serious unpredictable behaviours for your code.
What you're missing here is the concept of variable scoping in Java. count
is merely a shorthand for this.count
. So, given your code what the resolver does here, after the invocation of the getCounter()
method, is:
getCounter()
as an instance of StepCounter
classCounter
, so the context is switched over Counter
classgetCounter()
in Counter
classcount
getCounter()
is non-static, so count
is actually this.count
(if getCounter()
were to be static it would be Counter.count
)this.count
resolves to value 0
in the scope of the instance of Counter
class0
is returnedUpvotes: 1
Reputation: 8885
In Java, fields can't be overridden. Only methods can be overriden. So having a 'count' variable in StepCounter doesn't override the 'count' field in the super class 'Counter'. It just creates another field. However 'getCount' method returns the value of the 'count' field in the superclass. To have the desired functionality need to override the 'getCount' method in the StepCounter class.
Upvotes: 1