[英]protected static member for inherited class
我有幾個類都繼承相同的基類,並且需要具有在啟動時在函數中初始化的靜態屬性。 我是這樣實現的:
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)
}
因此,該類在開始時會初始化靜態成員。 但是似乎它為整個基類設置了模型的值,因此所有類實際上都具有相同的模型。
我需要model
是靜態的,因為每個子類只需要存在一次。 我的問題是如何在每個子類中擁有一個靜態模型,同時仍然確保它在父類中定義(因此,如果一個類未定義它,則在父類中定義)。
受保護的靜態成員在繼承的類中的預期行為是什么? 我應該如何為每個類都具有該成員的版本,並且仍然是靜態的(我不想讓每個實例重復該成員)?
我的問題是如何在每個子類中擁有一個靜態模型,同時仍然確保它在父類中定義(因此,如果一個類未定義它,則在父類中定義)。
沒辦法,因為,靜態成員和多態性,繼承不會同時發生
繼承不適用於靜態字段(即類字段)。 因此,只有一個字段Base.model
。 Inherited.model
引用相同的字段。
如果您確實需要模型的解析是自動的,而不是讓devoloper確保一致性,那么您需要自己實現整個機制,因為Java的任何語言功能都不會直接解決這個問題。
一種選擇是沿着Singleton
路線走,在那里Singleton
將是Model
工廠。 與其直接訪問靜態字段以獲取模型,不如要求相應類的工廠單例獲取它。 工廠本身將繼承基工廠,因此您可以通過多態性獲得“自動默認”行為。
正如其他答案所建議的那樣,靜態成員的作用域是類級別的,而不是對象級別的,總之,它不是繼承層次結構的一部分。 靜態成員的類名只是一個額外的名稱空間限定符。 這是有關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;
}
}
界面中隱藏了涉及靜態成員的事實,這是一個巨大的勝利。 如果到達無需使用靜態成員即可解決此問題的地步,則此處的類層次結構的客戶端將不會受到影響,因為訪問模型根本不會公開使用靜態成員的實現細節。
也許以某種方式管理模型對象:
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());
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.