我有几个类都继承了相同的基类,需要有一个在启动时在函数中初始化的静态属性。我这样实现了它:
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
是静态的,因为每个子类只需要存在一次。我的问题是如何为每个子类创建一个静态模型,同时仍然确保它在父类中定义(因此,如果类没有定义它,则在父类中定义)。
继承类中受保护静态成员的预期行为是什么?我应该如何为每个类创建这个成员的版本,仍然是静态的(我不希望它为每个实例复制)?
答案 0 :(得分:2)
我的问题是如何为每个子类创建一个静态模型,同时仍然如此 确保它在父类中定义(所以如果一个类没有 定义它,它在父类中定义。)
没办法,因为,静态成员和多态,继承不能一起使用
答案 1 :(得分:1)
继承不适用于静态字段(即类字段)。因此,只有一个字段Base.model
。 Inherited.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());
}
}
}