java匿名クラスが同時に実装およびサブクラス化できないのはなぜですか? それとも構文が原因ですか?
5 に答える
java匿名クラスが同時に実装およびサブクラス化できないのはなぜですか?
構文上の理由から 99% だと思います。型パラメーターは交差型( <T extends InterfaceX & InterfaceY>
) もサポートしているため、そのような機能によって矛盾や複雑さが生じることはないと思います。
次のような式new (InterfaceX & InterfaceY)() { ... }
は、たとえば次のようなものにコンパイルできます
interface InterfaceXandY extends InterfaceX, InterfaceY {}
... new InterfaceXandY() { ... }
そのような機能が追加されていない理由は、単純な回避策があるまれな使用例であるためである可能性が最も高いです。
やや関連するメモについて。たとえば、次のようにしてラムダを実装させることができますSerializable
Runnable r = (Runnable & Serializable)() -> System.out.println("Serializable!");
ラムダをシリアル化する方法を参照してください。
いわゆる匿名クラスは 100% 通常のクラスです。java.lang.reflect.Proxy と InvocationHandler を使用すると、ファンキーな結果が得られる可能性がありますが、これは最も汚い方法です。
より簡単な方法には、メソッドでクラスを宣言し、「implements」を追加するだけです。
匿名クラスは、"1 回限りの" クラスを迅速かつ簡潔に構築する方法として提供されています。あなたの質問は、anon クラスを複数の方法で使用しようとしていることを示唆しています (少なくとも 1 つのインターフェイスと 1 つの拡張)。この場合、その anon クラスを完全なクラスに昇格させると、より読みやすく、保守しやすくなります。
これにより、クラスのカプセル化をより適切に管理できるため、予期しない副作用も回避できます。
これに関するハックを発見
ファイルウィッチの下部にインターフェイスを作成し、実装するすべてのインターフェイスを拡張してから、これを実装する匿名クラスを作成します。
クロージャーは、何よりも時間のプレッシャーのために、最初は Java から取り残されていました。Java の初期の頃、クロージャの欠如は非常に苦痛だったので、内部クラスが生まれました。これは、多くの難しい問題を回避しようとする不快な妥協でした。しかし、非常に多くの設計上の問題でよくあることですが、単純化によって実際に問題が解決されることはなく、問題が移動しただけです。
興味深いことに、ラムダ式とクロージャーが Java に追加され、今回は内部クラスとは異なる何かが装備されているため、2 つ目のインターフェイスがマーカー インターフェイスであれば、複数のインターフェイスで構成されたオブジェクトをオンザフライで定義できます。
interface Bar {
default String getName() { return "Bar"; }
}
Object o = (Comparable<Integer> & Bar) (x,y) -> x > y ? x : y;
Bar b = (Bar) o;
System.out.println(b.getName()); //Bar
これは、JDK 8 の最新ビルド (2013 年 3 月 12 日) で完全にコンパイルおよび実行されます。ですから、今回はこの問題についてもっと考えているようです。