率直に言って、Javaの方法は、そのような状況をまったく回避することです。通常、Javaプログラマーは、ポリモーフィズムを壊さないようにさらに努力します(そして、多くの確立されたパターンを使用します)。したがって、タイプをオンにすることは悪い習慣と見なされます。
最も簡単な解決策と@optionalの直接変換は、instanceofを使用し、必要なメソッドを拡張するインターフェイス内にオプションのメソッドを含めることです。
interface MyProtocol {
void required1();
void required2();
}
interface MyProtocolWithOptional extends MyProtocol {
void optional1();
void optional2();
}
その後:
public static void test(MyProtocol mp) {
mp.required1();
if (mp instanceof MyProtocolWithOptional) {
((MyProtocolWithOptional)mp).optional1();
}
}
多くのインターフェースがあり、アプリケーションが実行時に拡張可能である場合は、機能パターン(http://java.dzone.com/print/4771)のようなソリューションを使用できます。このソリューションでは、各オブジェクトに使用可能なインターフェース( COMに少し似ていますが、COMとは少し異なります)。次のようなものから始めます。
interface ThingWithCapabilities<T> {
T interfaceFor(Class<T> inteface)
}
ThingWithCapabilitiesは、他のすべてによって拡張された基本インターフェースです。そして、実行時にそれを使用します。
public static void test(ThingWithCapabilities mp) {
if (mp.interfaceFor(MyProtocolWithOptions.class) != null) {
mp.interfaceFor(MyProtocolWithOptions.class).optional1();
}
}
良い点は、キャスティングがなくなったことです。より良い点は、MyProtocolWithOptionsインスタンスのライフサイクルをThingWithCapabilitiesのライフサイクルに結び付けないことです(たとえば、MyProtocolWithOptionsの単一のインスタンスを多くのThingWithCapabilitiesインスタンスに対応させることができます。一方、次の場合はこれを返すことができます。 MyProtocolWithOptionsを実装することがあります)。これをnullオブジェクトパターン(nullの代わりにMyProtocolWithOptions機能を持たない各ThingWithCapabilitiesによって返される、何もしないMyProtocolWithOptionsのstatlessインスタンスがある場合)と組み合わせると、さらに優れたコードを取得できます。
public static void test(ThingWithCapabilities mp) {
mp.interfaceFor(MyProtocolWithOptions.class).optional1();
}
あなたが何か大きなものを書いているのでない限り、このアプローチはおそらく複雑です。それは面白いので、私はちょうどそれについて言及しました(そして私はいくつかのペットプロジェクトでそれをうまく使用しました)。