首先,我读了埃里克森对"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