まず、erickson の「Java インターフェースで静的メソッドを定義できないのはなぜですか?」に対する有益な回答を読みました。. この質問は「なぜ」ではなく、「どうやって?」についてです。
編集:私の元の例は不適切でしたが、以下に残します。
ほとんどの場合、私がやりたいことはやり過ぎだと確信していますが、それが必要になるシナリオが 1 つあります。
もう一度ParametricFunction
例を挙げます。ここで、ベッセル関数のような複雑な関数を考えてみましょう。ここではルックアップ テーブルが適切です。これは初期化する必要があるため、2 つのオプションはパラメーターをコンストラクターに直接渡すか、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、ここではインターフェイスを実装する抽象クラスで十分です)
ParametricFunction
ここで、が特定のパラメータ (正の整数など) のみを許可すると仮定します。コンストラクターに渡されたパラメーターの有効性を確認する方法は? -exceptionIllegalArgument
をスローすることも可能ですが、 acheckParametersValidity(double[] parameters)
の方がはるかに便利です。ただし、パラメータのチェックは構築前に行う必要があるため、静的メソッドである必要があります。ParametricFunction
そして、インターフェイスを実装するすべてのクラスがこの静的メソッドを定義していることを確認する方法を知りたいのです。
私はこの例がかなり人為的であることinit
を知っています.インターフェースを介してメソッドを単純に使用しない理由は議論の余地があります.私はまだ答えを知りたいです. 嫌ならアカデミックな問題と考えてください。
(元の例)
したがって、基本的には、1 つのインターフェイスで通常のメソッドとメソッドなどの両方を提供する必要があり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標準では許可されていないため、これに最も近いものは何ですか?
この背後にあるアイデアは、いくつかParametricFunction
の をパッケージに入れ、Reflection を使用してそれらをすべてリストし、ユーザーがどれをプロットするかなどを選択できるようにすることです。明らかに、利用可能な の配列を含むローダー クラスを提供できますがParametricFunction
、新しいものが実装されるたびに、そこに追加することも覚えておく必要があります。
編集:それを呼び出す例は
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});
ます。