我70%確信這是不可能的,但有沒有辦法確保子類具有特定的構造函數或工廠方法?強制子類具有特定的工廠方法或構造函數
在這種情況下,我想創建一個StringSerializable
,要求子類有以下幾種方法
toString
,其將對象到String
。fromString
,它從String
獲取實例。
很明顯,在第一種情況下,我只能使toString
爲抽象。另一方面,擁有非靜止的fromString
似乎是有問題的。但是,我無法創建抽象靜態方法。我也不認爲構造函數是完全合適的。
我70%確信這是不可能的,但有沒有辦法確保子類具有特定的構造函數或工廠方法?強制子類具有特定的工廠方法或構造函數
在這種情況下,我想創建一個StringSerializable
,要求子類有以下幾種方法
toString
,其將對象到String
。fromString
,它從String
獲取實例。很明顯,在第一種情況下,我只能使toString
爲抽象。另一方面,擁有非靜止的fromString
似乎是有問題的。但是,我無法創建抽象靜態方法。我也不認爲構造函數是完全合適的。
你是對的;在編譯時無法強制它。你可以在運行時使用各種技巧(比如在測試中使用反射),但這只是關於它。
但問問自己:爲什麼你想要嗎?你不能動態調用一個靜態方法或構造函數(除了通過反射),那麼如果你有它們,那麼你將如何使用那些所需的工廠呢?
如果只是爲了保持代碼的一致性(這是一件好事!),那麼您只需在開發代碼庫時確保一致性。基礎類中的評論可以在這裏發揮很大作用,因爲可以編寫評論和其他「軟」技術。
如果您打算在反射中使用工廠,那麼可以在測試中使用類似的反射來確保每個子類都具有它需要的位。
另一種選擇是創建一個非靜態工廠:
public interface FooMaker() {
Foo create(String arg);
}
...和使用,而不是靜態fromString
方法。
還有,你有同樣的問題「我如何確保每個子類都有一個FooMaker
執行?」我再次說,你不應該擔心這一點。如果你將FooMaker
作爲你的代碼的「起點」而不是子類,那麼這個子類在做什麼並不重要;所有重要的是你的FooMaker
s給你一個從字符串到Foo
s的方法,並且每個Foo
都有一個返回字符串的方法。
它基本上只是爲了代碼一致性。我之前所做的是要求一個非靜態工廠,但實際上只是用來引用一個靜態工廠。 – 2015-02-10 01:10:50
以下代碼確保每個子類都需要實現靜態方法,如果子類沒有實現該方法,則在構造類時會失敗,儘可能接近編譯時錯誤,但不能編譯時間
拋出的異常是很清楚的,並開始
public abstract class Base {
static Functional test;
static {
if(test == null) {
throw new RuntimeException("You need to provide an implementation for the implemntMe method in class base");
}
}
private interface Functional {
Base implementMe(int whatever, boolean anotherParameter);
}
public static void main(final String[] args) {
}
}
專用接口結構可確保只有lambda表達式可以用來implemen時PROGRAMM將立即失效t爲方法
子類必須像這樣
public SubClass extends Base {
static {
test = (int whatever, boolean anotherParameter) -> {
Subclass tmp = new Subclass();
//construct object
tmp.setWhatever(whatever);
return tmp;
}
}
}
lamdas是這樣實現的功能接口聯方法,它只有一個抽象方法
的接口,你也可以聲明在任何其他地方公開使用,並使用匿名內部類 實現它,但我的方式確保程序員必須複製和粘貼代碼才能重用它, 或需要從另一個類複製Functional對象
對不起,我不太熟悉靜態和內部這種混合類型。我想知道你是否可以證明子類將要做什麼? – 2015-02-10 02:59:16
您可以在構造函數中使用reflection。 – immibis 2015-02-10 00:58:45
@immibis我聽說那可能是不安全的,因爲有時反射不起作用。 – 2015-02-10 00:59:14
也反射非常緩慢,應該避免在生產代碼一般afaik – 2015-02-10 01:00:52