4

假设我有 3 个课程:

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
    }
}

在这种情况下,我知道并希望 B 的 var 字段隐藏 Foo 并且仍然以类似的方式使用(打印它的值或执行一些计算或其他)。
故意隐藏字段会使代码难以阅读,但这是一个例外,还是只是糟糕的设计?

编辑:
我确实希望 A 从 Foo 继承“var”,但我也希望 B 继承除 var 之外的所有内容。

编辑 2:
忘记将访问修饰符添加到 var。

4

2 回答 2

5

您不能以与可以覆盖方法相同的方式“覆盖”字段。您需要使用方法覆盖来实现此行为。例如:

class Foo
{    
    private String var;

    Object getVar() {
        return var;
    }
}

class B extends Foo
{
    private int var;

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

编辑:根据您的评论:

Foo'svar是 type List<String>B'svar是 type List<Item>whereItem是一个单独的类。如您所知,两者都使用列表但具有不同的模板类型,并且两者仍然做同样的事情(浏览列表并对元素做一些事情)

听起来你的类应该是通用的,例如:

abstract class Foo<T> {

    List<T> list;

    // common logic
}

class A extends Foo<String> { }

class B extends Foo<Item> { }

不要太从字面上理解这段代码——它只是为了建议可能的设计。

于 2013-07-18T17:04:09.020 回答
0

我的偏好是避免在子类中直接访问超类中的字段,因为它减少了对超类实现的依赖。(肯定有一段时间我会创建字段protected,因为我确实希望从子类中显式使用它们,但这不是常态)。

我更喜欢做的是将字段访问封装在 getter/setter 方法中,并有意使它们成为受保护的或公共的,以便子类可以显式地覆盖它们。通常,我经常发现直接字段访问会阻止重构或稍后修改实现,因为会导致更新更多的类而不是必要的。

在您的情况下,如果您正在处理其他人编写的代码,并且无法访问基类的源代码,那么这是有道理的。但否则我不会这样做,因为对于其他开发人员来说,您故意隐藏该字段可能并不那么明显。如果这只是供您自己使用(而不是其他开发人员),那么实际上,我认为这并不重要。

于 2013-07-18T17:09:33.107 回答