有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java对子类中的超类隐藏字段

假设我有三门课:

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


共 (2) 个答案

  1. # 1 楼答案

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

    我更喜欢做的是将字段访问封装在getter/setter方法中,并有意将它们设置为受保护的或公共的,以便子类可以显式重写它们。总的来说,我经常发现,直接字段访问会导致更新的类超过需要的数量,从而妨碍以后重构或修改实现

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

  2. # 2 楼答案

    不能像重写方法那样“重写”字段。您需要使用方法重写来实现此行为。例如:

    class Foo
    {    
        private String var;
    
        Object getVar() {
            return var;
        }
    }
    
    class B extends Foo
    {
        private int var;
    
        @Override
        Object getVar() {
            return var;
        }
    }
    

    编辑:根据您的评论:

    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)

    听起来你的类应该是泛型的,例如:

    abstract class Foo<T> {
    
        List<T> list;
    
        // common logic
    }
    
    class A extends Foo<String> { }
    
    class B extends Foo<Item> { }
    

    不要把这个代码看得太字面——它只是建议可能的设计