小编典典

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

java

首先,我阅读了埃里克森对“为什么不能在Java接口中定义静态方法?”的有用答复。。这个问题不是关于“为什么”的问题,而是关于“然后如何做”的问题。


编辑:我的原始示例不适当地,但我将其保留在下面。

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

我再举一个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) { ... }
}

这涉及另一个问题,即接口中构造函数的不可能。那里有什么好的解决方案?我当然可以使用该init(double[] parameters)方法,但是我提到了为什么不这样做的原因。
(编辑:确定,在这里实现接口的抽象类就可以了)

现在,我们假设ParametricFunction只允许某些参数,例如正整数。如何检查传递给构造函数的参数的有效性?抛出IllegalArgument-exception有可能,但是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);
}

然后

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标准不允许这样做,最接近的是什么?

其背后的想法是将几个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));
}

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


阅读 189

收藏
2020-11-19

共1个答案

小编典典

不能 要求类通过接口实现特定的静态方法。就Java而言,这毫无意义。接口在实现接口的类中强制存在特定的非静态方法。那就是他们的工作。

最简单的方法肯定是拥有某种工厂类来生成其他工厂的实例。是的,这确实意味着您必须记住在添加新实例时使该工厂保持最新状态,但是由于在执行新实现时要做的第一件事就是对其进行测试(您确实要对其进行测试,是吗?),很快就会解决这个问题!

2020-11-19