terrorcell
terrorcell

Reputation: 187

Hide a field from a superclass in a subclass

Let's say I have 3 classes:

class Foo
{    
    protected String var;
    public void doSomething()
    {
         // does something with var
    }
}

class A extends Foo
{
    public void doSomething()
    {
        // uses var slightly differently to Foo
    }
}

class B extends Foo
{
    protected int var; // hides Foo's var field
    public void doSomething()
    {
        // does something with B's var, but still in a similar fashion to Foo
    }
}

In this case, I know and want B's var field to hide Foo's and still be used in a similar way (printing its value or performing some calculation or whatever).
Intentionally hiding fields can make code hard to read, but is this an exception to that, or is it still just poor design?

Edit:
I do want A to inherit 'var' from Foo but I'd also like B to inherit everything except for var.

Edit 2:
Forgot to add the access modifiers to var.

Upvotes: 4

Views: 3868

Answers (2)

Paul Bellora
Paul Bellora

Reputation: 55233

You can't "override" fields in the same way that methods can be overridden. You'll need to use method overriding to implement this behavior. For example:

class Foo
{    
    private String var;

    Object getVar() {
        return var;
    }
}

class B extends Foo
{
    private int var;

    @Override
    Object getVar() {
        return var;
    }
}

Edit: Based on your comment:

Foo's var is of type List<String>, and B's var is of type List<Item> where Item is a separate class all together. As you can tell, both use Lists but with different template types, and both still do the same thing (go through the list and do something to the elements)

It really sounds like your classes should be generic, for example:

abstract class Foo<T> {

    List<T> list;

    // common logic
}

class A extends Foo<String> { }

class B extends Foo<Item> { }

Don't take this code too literally - it's just to suggest the possible design.

Upvotes: 5

Sam Goldberg
Sam Goldberg

Reputation: 6801

My preference is to avoid direct field access of fields in a super class in a subclass, because it reduces dependencies on the implementation of the super class. (There are definitely some time that I will make fields protected because I do expect to explicitly use them from a subclass, but that is not the norm).

What I prefer to do is to encapsulate field access inside getter/setter methods, and to intentionally make them protected or public so subclasses can override them explicitly. In general, I often find that direct field access inhibits refactoring or modifying the implementation later, by causing more classes to be updated than should be necessary.

In your case, if you are dealing with code someone else wrote, and don't have access to the source of the base class, then it makes sense. But otherwise I wouldn't do it, because it may not be so obvious to other developers that you are intentionally hiding the field. If this is only for your own use (and not other developers), then practically speaking, I don't think it matters much.

Upvotes: 0

Related Questions