簡體   English   中英

繼承類的受保護靜態成員

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM