"I"のインターフェイス "I"と "I"の実装が "C1"〜 "Cn"とするとします。インターフェースとインプリメンテーションが変更できない外部ライブラリに存在するとします。最後に、Java 8を使用していると仮定します。
"I"のすべての実装の機能を拡張します。
"I"が変更可能な場合、OracleがストリーミングAPIを公開したときに、デフォルトの実装で新しいメソッドを追加することができます。残念ながら "私"は変更できません。
現在の解決策は次のとおりです。
"I"を拡張し、必要な新しいメソッドをデフォルトインターフェイスとして含む新しいインターフェイス "IX"を作成します。
"C1"〜 "Cn"は "IX"ではなく "I"を実装するため、新しい機能を利用するために実装 "CX1"〜 "CXn"が必要です。これは私が好きではない部分です。私は匿名のクラスのようにその場で実装を作成する方法を好むでしょう。 「CXN」に「CX1」の定義は、私はそれらの定型を考慮して取得したいと思い、まったく体の実装を必要としないので
これより少ないコードで既存のインターフェイス実装を拡張する方法はありますか?
// Instantiate existing "C9" implementation of "I"
I object = new C9();
// Definition of interface "IX"
public interface IX extends I {
default void newMethod() {
// Do something
}
}
// Example definition of implementation "CX9"
// Off course, this needs to be done for all "C1" to "Cn".
public class CX9 extends C9 implements IX {}
// Instantiate extended implementation "C9"
IX object = new CX9();
:ここ
は私のアプローチを説明するためにいくつかのコード例ですそれらを取り除く。私は実際に次のようなものを好むだろう。
IX object = new (C9 implements IX)() {};
もちろん、有効なJavaコードはありません。このアイデアは、追加インターフェイス(「IX」)を実装する既存のクラス(「C9」)に基づく匿名クラスを作成することです。標準のJavaでこれを行う方法はありますか?
私は間違いなく標準のJavaとバイトコード操作なしでこれをしたいと思います。もちろん、私はラッパーや動的なプロキシを使うことができますが、 "I"と "C"は多くのメソッドを定義しています。したがって、私はさらに定型的なコードで終わるだろう。
この質問は純粋に学術的なものであると認めます。なぜなら、結局のところ、「I」の実装ごとに1行のコードを削除するだけだからです。しかし、私はまだ可能な解決策に興味があります。
より実践的なアプローチが欲しい場合は、基本インターフェイスを変更することなく、未知の実装セットにストリーミングAPIのようなものを適用したいとします。
ありがとうございます。
既存のCnクラスにはすべてデフォルトのコンストラクタしかないと言っていますか?そのすべてが容易にサブクラス化できるように? – GhostCat
@PavneetSinghいいえ!いいえ!コードレビューでは、[トピック外の]疑似的な疑問を考慮します(http://codereview.stackexchange.com/help/on-topic)。 – Mast
@PhilippSander上記のコメントを参照してください。誰かが起動すると、移行は拒否されます。私は確信しています。コードレビューはそれを受け付けません。 – Mast