≡ Menu

Rocket Java: Shadowing private variables in subclasses

This morning, a user on ##java asked if private variables could be shadowed in subclasses.

Upon being asked to try it and see, the user said that they didn’t have the time, which was ironic (and wrong), but errr… what the heck, I’ll write a test case to demonstrate that no, shadowing private variables (and retaining their reference) was not workable: the superclass will use its own reference, not a subclass’.

So let’s see some code:

public class T {
    private boolean b=true;

    public void doSomething() {
        System.out.println(b);
    }

    public static void main(String[] args) {
        T t=new U();
        t.doSomething();
    }
}

class U extends T {
    private boolean b=false;
}

Upon execution, this outputs true.

Now, would this change if we used an accessor instead? Let’s add one to T:

public boolean getB() { return this.b;}

… and nope, nothing changes. The main point here is actually that shadowing fields like this (shadowing the actual field, not methods) is a Bad Idea, and doesn’t work, private or not. (If you change the visibility away from private, the result still doesn’t change.

What’s more, you generally don’t want to do it, and wouldn’t want to even if it were possible, because … what would be your point? You’d be effectively trying to change the semantic of the field, if you needed to do this – and this alters the superclass/subclass relationship in fundamentally unhealthy ways.

If you need a different value in the field you want to shadow, don’t shadow – just offer a protected mutator, and have the subclass set the value.

{ 0 comments… add one }

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.