First of all, I read erickson's useful reply to "Why can’t I define a static method in a Java interface?". This question is not about the "why" but about the "how then?".
Edit: my original example was ill-posed, but I'll leave it below.
While I am now convinced that in most cases what I want to do is overkill, there is one scenario where it could be needed:
I'll take the ParametricFunction
example again. Now let's take a complicated function, like the Bessel functions, where a lookup-table is appropriate. That has to be initialised, so the two options are passing the parameters directly to the constructor or providing a init(double[] parameters)
. The latter has the disadvantage that getValue(double x)
must check the initialisation every call (or the ArrayIndexOutOfBoundsException
must be considered as initialisation-check), so for time-critical applications I'd prefer the constructor-method:
interface ParametricFunction {
public double getValue(double x);
}
class BesselFunction implements ParametricFunction {
public BesselFunction(double[] parameters) { ... }
public double getValue(double x) { ... }
}
Which touches another problem, the impossibility of constructors in interfaces. What would be a good solution there? I could of course use the init(double[] parameters)
approach, but I mentioned my reason why not.
(Edit: OK, here an abstract class implementing the interface would do)
Now let's assume the ParametricFunction
allows only certain parameters, e.g. positive integers. How to check the vailidity of parameters passed to the constructor? Throwing an IllegalArgument
-exception would be a possibility, but a checkParametersValidity(double[] parameters)
seems a lot more convenient. But checking the parameters needs to be done before construction, so it has to be a static method. And that's where I'd really like to know a way to make sure every class implementing the ParametricFunction
interface does define this static method.
I know this example is rather artificial, and the reason for not simply using a init
method through the interface is debatable, I'd still like to know the answer. Consider it an academic question if you don't like it.
(original example)
So basically I want one Interface to provide both usual methods and e.g. a getSimilarObject
method. For (a made up) example
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);
}
and then
public class Parabola implements ParametricFunction {
/** @return f(x) = parameters[0] * x2 + 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);
}
}
Since this is not allowed in the current Java standard, what is the closest thing to this?
The idea behind this is putting several ParametricFunction
s in a package and use Reflection to list them all, allowing the user to pick e.g. which one to plot. Obviously one could provide a loader class containing an array of the available ParametricFunction
s, but every time a new one is implemented one has to remember adding it there, too.
edit: An example to call it is
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));
}
and calling evaluate("Parabola", 1, new double[]{1,2,0});
.
See Question&Answers more detail:
os