受保护的继承类的静态成员

时间:2014-01-11 13:25:53

标签: java inheritance static polymorphism

我有几个类都继承了相同的基类,需要有一个在启动时在函数中初始化的静态属性。我这样实现了它:

public abstract class Base {
    protected static Model model;
}

public class Inherited extends Base {
    static {
        model = initializationFunction();
    }
}
public class OtherInherited extends Base {
    static {
        model = otherInitializationFunction();
    }
}
// Example of use
Base[] inheriteds = new Base[] { new Inherited(), new OtherInherited() };
for (int i = 0; i < inheriteds.length; i++)  {
     doStuff(inheriteds[i]).model; // This will always use the same model (last defined)
}

因此该类在start时初始化静态成员。但似乎它为整个基类设置了模型的值,因此所有类实际上都具有相同的模型。

我需要model是静态的,因为每个子类只需要存在一次。我的问题是如何为每个子类创建一个静态模型,同时仍然确保它在父类中定义(因此,如果类没有定义它,则在父类中定义)。

继承类中受保护静态成员的预期行为是什么?我应该如何为每个类创建这个成员的版本,仍然是静态的(我不希望它为每个实例复制)?

5 个答案:

答案 0 :(得分:2)

  

我的问题是如何为每个子类创建一个静态模型,同时仍然如此   确保它在父类中定义(所以如果一个类没有   定义它,它在父类中定义。)

没办法,因为,静态成员和多态,继承不能一起使用

答案 1 :(得分:1)

继承不适用于静态字段(即类字段)。因此,只有一个字段Base.modelInherited.model指的是同一个字段。

答案 2 :(得分:1)

如果你真的需要自动解决模型而不是让devoloper确保一致性,那么你需要自己实现整个机制,因为Java的语言特性不会直接处理它。

其中一个选项是Singleton路线,其中单身人士是Model工厂。不是直接访问静态字段来获取模型,而是要求相应类的工厂单例来获取它。工厂本身会将基础工厂子类化,因此您可以通过多态获得“自动默认”行为。

答案 3 :(得分:1)

正如其他答案所暗示的那样,静态成员的范围是在类级别而不是在对象级别,简而言之,它们不是继承层次结构的一部分。静态成员的类名只是一个额外的名称空间限定符。以下是static关键字的一个非常好的概要:http://mindprod.com/jgloss/static.html

至于解决你的问题,我在使用静态成员的同时对此进行了破解。如果你真的必须让子类的每个实例共享同一个模型实例,同时保持与基类的某种接口兼容性,那么考虑做类似如下的事情:

public abstract class Base {
    public abstract Model getModel();
}

public class Inherited extends Base {
    static private Model model = initializationFunction();

    public Model getModel() {
        return model;
    }
}

public class OtherInherited extends Base {
    static private Model model = otherInitializationFunction();

    public Model getModel() {
        return model;
    }
}

这里涉及静态成员的事实是从界面隐藏的,这是一个很大的胜利。如果在不使用静态成员的情况下达到可以解决此问题的程度,那么此类层次结构的客户端将不会受到影响,因为访问模型根本不会公开使用静态成员的实现细节。

答案 4 :(得分:0)

也许以某种方式管理模型对象:

public abstract class TestBase {

    private static Map<Class, Object> modelObjects = new HashMap<>();

    public static void setModel(Class _class, Object model) {
        modelObjects.put(_class, model);
    }

    public static Object getModel(Class _class) {
        return modelObjects.get(_class);
    }

    public static class Inherited extends TestBase {

        static {
            setModel(Inherited.class, new Object());
        }
    }

    public static class OtherInherited extends TestBase {

        static {
            setModel(OtherInherited.class, new Object());
        }
    }
}