有没有办法确保实现接口的类实现静态方法?

Tob*_*ler 21 java static interface abstract

首先,我阅读了erickson对"为什么我不能在Java接口中定义静态方法?"的有用回复..这个问题不是关于"为什么"而是关于"当时如何?".


编辑:我原来的例子不合适,但我会把它留在下面.

虽然我现在确信在大多数情况下我想做的事情是矫枉过正,但有一种情况可能需要:

我再举一个ParametricFunction例子.现在让我们来看一个复杂的函数,比如Bessel函数,其中查找表是合适的.这必须初始化,因此两个选项是将参数直接传递给构造函数或提供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) { ... }
}
Run Code Online (Sandbox Code Playgroud)

这涉及另一个问题,接口中构造函数的不可能性.那里有什么好的解决方案?我当然可以使用这种init(double[] parameters)方法,但我之所以提到我的原因.
(编辑:好的,这里实现接口的抽象类会这样做)

现在让我们假设ParametricFunction只允许某些参数,例如正整数.如何检查传递给构造函数的参数的真实性?抛出一个IllegalArgument例外是可能的,但checkParametersValidity(double[] parameters)似乎更方便.但是在构造之前需要检查参数,因此它必须是静态方法.这就是我真正想知道的方法,以确保实现ParametricFunction接口的每个类都定义了这个静态方法.

我知道这个例子是相当人为的,不仅仅是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);
}
Run Code Online (Sandbox Code Playgroud)

然后

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

由于在当前的Java标准中不允许这样做,最接近它的是什么?

这背后的想法是将几个ParametricFunctions放在一个包中并使用Reflection将它们全部列出,允许用户选择例如要绘制哪一个.显然,人们可以提供一个包含可用ParametricFunctions 数组的加载器类,但每次实现一个新的时,都必须记住在那里添加它.

编辑:调用它的一个例子是

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));
}
Run Code Online (Sandbox Code Playgroud)

并打电话evaluate("Parabola", 1, new double[]{1,2,0});.

Don*_*ows 17

不能要求类通过接口实现特定的静态方法.在Java术语中它没有任何意义.接口强制在实现接口的类中存在特定的非静态方法; 这就是他们所做的.

最简单的方法是使用某种工厂类来生成其他工厂的实例.是的,这确实意味着你必须记住在添加新实例时保持该工厂的最新状态,但是,当你做一个新的实现时,你要做的第一件事是测试它(你测试它,是吗?)你'我会很快发现这个问题!

  • @Sebastien:为什么这两个类没有兴趣共享完全相同的静态方法名称?使用反射这可能是确保方法存在的唯一方法.我想`getDescription()`返回类的描述.为什么它会在不同的情况下改变?这就是为什么我希望这种方法是静态的,并且以类似接口的方式强制执行它. (11认同)
  • 为什么没有意义?Interface不能要求类提供`static public String getDescription()`吗?我并不把它与javadoc混淆,我的意思是例如用户选择`ParametricFunction`以适应数据的GUI,并且如果单独的名称不那么直观,可能想知道每个函数的作用.然后认为`ParametricFunction`是一个更复杂的东西,因此实例化会消耗很多时间,特别是当提供一个包含100`RefidicFunctions的描述的列表时,最终只会选择一个. (7认同)
  • 没有意义,因为你在类而不是实例上调用静态方法.两个类没有兴趣共享完全相同的静态方法名称,因为您没有从接口调用此方法...您期望getDescription()返回什么?班级的描述?还是当前实例类的描述? (2认同)