The Problem
In a nutshell, shadowed variables come from the declared type of an object, but overridden methods are run from the constructed object.
Ok, that isn't very clear, so here is some code to make it simpler. It's all in one file called Derived.java:
class Base { public int x = 0; public String aMethod() { return "Base"; }; } public class Derived extends Base { private String secretmessage = "a secret!"; public int x = 1; public String aMethod() { return "Derived " + this.secretmessage; } public static void main(String[] args) { Base b = new Derived(); // System.out.println("x:aMethod = " + b.x + ":" + b.aMethod()); // } }
The output of this when run is:
x:aMethod = 0:Derived a secret!
What that shows is that b.x returned the Base class's variable x, and b.aMethod() returned the Derived class's method aMethod.
Access to Unreachable Data
In Derived, the function aMethod returns a string that contains the contents of the private instance variable secretmessage. If I were to substitute b.aMethod() with b.secretmessage, I would get a compiler error because b.secretmessage is not available in class B:
Derived.java:23: error: cannot find symbol System.out.println("x:aMethod = " + b.x + ":" + b.secretmessage); ^ symbol: variable secretmessage location: variable b of type Base 1 error
But, I can access the variable via aMethod! This also means I could execute any method in Derived, as long as it overrides the same method in Base.
If an able Java programmer did not know this, then reading the code may be problematic: one would expect a base class's method to run when in fact the derived class method was run. Likewise, the opposite could be said for a shadowed variable.
Bottom line: be aware of the shadowing and overriding rules.
No comments:
Post a Comment