首先,我讀了埃裏克森對"Why can’t I define a static method in a Java interface?"的有用回覆。這個問題不是關於「爲什麼」,而是關於「怎麼做?」。 有沒有辦法確保實現接口的類實現靜態方法?
編輯:我最初的例子不適合,但我會在下面留下它。
雖然我現在相信,在大多數情況下,我想要做的就是矯枉過正,有一個場景可能需要它:
我將再次參加例子。現在讓我們來看一個複雜的函數,如Bessel functions,其中查找表是合適的。這必須進行初始化,所以這兩個選項直接將參數傳遞給構造函數或提供init(double[] parameters)
。後者的缺點是getValue(double x)
必須檢查初始化每次呼叫(或ArrayIndexOutOfBoundsException
必須被視爲初始化檢查),所以對時間要求嚴格的應用我寧願構造法:
interface ParametricFunction {
public double getValue(double x);
}
class BesselFunction implements ParametricFunction {
public BesselFunction(double[] parameters) { ... }
public double getValue(double x) { ... }
}
其中涉及另一個問題是接口中構造函數的不可能性。那將是一個很好的解決方案?我當然可以使用init(double[] parameters)
的方法,但我提到了我的理由。
(編輯:OK,這裏實現接口的抽象類會做)
現在讓我們假設只允許某些參數,例如正整數。如何檢查傳遞給構造函數的參數的威力?拋出一個IllegalArgument
- 將是一種可能性,但checkParametersValidity(double[] parameters)
似乎更方便。但是檢查參數需要在施工前完成,因此它必須是一個靜態方法。這就是我真正想知道的方法,以確保實現接口的每個類都確定了這種靜態方法。
我知道這個例子是相當人爲的,不通過接口簡單地使用init
方法的原因是有爭議的,我仍然想知道答案。如果你不喜歡它,請考慮一個學術問題。
(原來的例子)
所以基本上我想一個接口以提供通常的方法和例如一種getSimilarObject
方法。對於(一個由)例如
public interface ParametricFunction {
/** @return f(x) using the parameters */
static abstract public double getValue(double x, double[] parameters);
/** @return The function's name */
static abstract public String getName();
/** @return Whether the parameters are valid [added on edit] */
static abstract public boolean checkParameters(double[] parameters);
}
然後
public class Parabola implements ParametricFunction {
/** @return f(x) = parameters[0] * x² + parameters[1] * x + parameters[2] */
static public double getValue(double x, double[] parameters) {
return (parameters[2] + x*(parameters[1] + x*parameters[0]));
}
static public String getName() { return "Parabola"; }
// edit:
static public boolean checkParameters(double[] parameters) {
return (parameters.length==3);
}
}
因爲這在目前的Java標準是不允許的,什麼是最接近這個?
這個想法背後是將幾個s放在一個包中,並使用Reflection將它們全部列出,從而允許用戶選擇例如哪一個要繪製。很顯然,可以提供一個包含可用的數組的加載器類,但是每次實現新的加載器時,都必須記住在其中添加新的加載器。
編輯:一個例子來調用它是
public double evaluate(String fnName, double x, double parameters) throws (a lot) {
Class<ParametricFunction> c = (Class<ParametricFunction>) ClassLoader.getSystemClassLoader().loadClass(fnName);
Method m = c.getMethod("getValue", x, parameters);
return ((double) m.invoke(null));
}
,並呼籲evaluate("Parabola", 1, new double[]{1,2,0});
。
爲什麼getValue必須是靜態的?如果getValue不是靜態的,你將能夠完成你想要的。 – nos 2010-04-22 08:50:46
然後,我不得不創建該類的一個實例。糾正我,如果我錯了,但關於它的目的,似乎沒有用。 – 2010-04-22 09:03:25
你的設計出了什麼問題。這不是面向對象。參數[]應該是Parabola類的實例字段,在構造函數中設置和檢查,並在getValue()類中使用。 – 2010-04-22 09:17:52