デフォルトの方法は何ですか?
Java 8がリリースされた後、新しいメソッドをインターフェイスに追加できますが、インターフェイスは実装クラスと互換性があります。開発するクラスライブラリは、複数の開発者が広く使用できるため、これは非常に重要です。 Java 8の前、クラスライブラリでインターフェイスがリリースされた後、インターフェイスに新しいメソッドが追加された場合、このインターフェイスを実装するアプリケーションは、インターフェイスの新しいバージョンを使用してクラッシュするリスクがあります。
Java 8では、そのような危険はありませんか?答えはノーです。
デフォルトメソッドをインターフェイスに追加すると、一部の実装クラスが利用できなくなる場合があります。
まず、デフォルトメソッドの詳細を見てみましょう。
Java 8では、インターフェイスのメソッドを実装できます(Java 8の静的メソッドもインターフェイスに実装できますが、これは別のトピックです)。インターフェイスに実装されているメソッドは、デフォルトメソッドと呼ばれ、キーワードデフォルトによって修飾子として識別されます。クラスがインターフェイスを実装する場合、インターフェイスに実装されたメソッドを実装できますが、これは必要ありません。このクラスは、デフォルトのメソッドを継承します。これが、インターフェイスが変更されたときに、実装クラスを変更する必要がない理由です。
もっと継承する時はどうですか?
クラスが複数の(たとえば、2つの)インターフェイスを実装すると、物事が複雑になり、これらのインターフェイスには同じデフォルトの方法があります。クラスはどのデフォルトメソッドを継承しますか?それらはどれもありません!この場合、クラスはデフォルトメソッド(のみ)を単独で実装する必要があります(ツリー上の高レベルのクラスを直接または継承する)。
1つのインターフェイスがデフォルトメソッドを実装し、もう1つのインターフェイスがデフォルトメソッドを要約として宣言する場合も同じことが言えます。 Java 8は、不明確なことを避け、厳密にしようとします。メソッドが複数のインターフェイスで宣言されている場合、デフォルトの実装は継承されず、コンパイル時間エラーが発生します。
ただし、クラスをコンパイルした場合、コンパイル時間エラーはありません。この時点で、Java 8は一貫性がありません。さまざまな理由で、独自の理由があります。ここで詳細に説明したり、詳細に説明したりしたくありません(バージョンがリリースされており、議論が長すぎて、このプラットフォームはこのように議論したことはありません)。
上記の場合、クラスは正常に実行できます。ただし、変更されたインターフェイスで再コンパイルすることはできませんが、古いインターフェイスで実行できます。次
両方のインターフェイスがデフォルトの実装を同じメソッドに提供する場合、実装クラスがデフォルトメソッドを実装しない限り(直接実装するか、実装のためにツリー上の高レベルクラスを継承しない限り、このメソッドを呼び出すことはできません。
ただし、このクラスは互換性があります。両方のインターフェイスでデフォルトの実装を持つメソッドを呼び出さない限り、新しいインターフェイスをロードしたり、実行したりすることさえできます。
例コード
上記の例を示すために、i1.javaとi2.javaの保存に使用される3つのサブディレクトリがあるC.Javaのテストディレクトリを作成しました。テストディレクトリには、クラスCのC.Javaのソースコードが含まれています。ベースディレクトリには、コンパイルおよび実行できるバージョンへのインターフェイスが含まれています。 I1にはデフォルトで実装されたM()メソッドが含まれており、I2にはメソッドが含まれていません。
実装クラスにはメインメソッドが含まれているため、テストで実行できます。コマンドラインパラメーターがあるかどうかを確認して、M()を呼び出してM()を呼び出さないテストを簡単に実行できるようにします。
パブリッククラスCはi1、i2 {public static void main(string [] args){c c = new c(); if(args.length == 0){cm(); }}} public interface i1 {default void m(){system.out.println( "hello interface 1"); }} public interface i2 {}次のコマンドラインを使用してコンパイルして実行します。
Javac -cp。:ベースC.Javajava -cp。:ベースChelloインターフェイス1
互換性のあるディレクトリには、抽象メソッドM()と未修飾I1インターフェイスを備えたI2インターフェイスが含まれています。
パブリックインターフェイスi2 {void m();}これは、クラスCをコンパイルするために使用することはできません。
Javac -cp。:互換性のあるc.javac.java:1:エラー:cは抽象的ではなく、i2publicクラスCの抽象的メソッドm()をオーバーライドしません。
エラーメッセージは非常に正確です。以前のコンパイルから取得したC.クラスがあるため、互換性のあるディレクトリにインターフェイスをコンパイルすると、実装クラスを実行できる2つのインターフェイスが表示されます。
Javac互換/i*.javajava -cp。:互換性のあるChelloインターフェイス1
誤解と呼ばれる3番目のディレクトリとI2インターフェイスには、M()メソッドも定義されています。
public interface i2 {default void m(){system.out.println( "hello interface 2"); }}私たちはそれをコンパイルするのに飽きるべきではありません。 M()メソッドは2回定義されていますが、実装クラスは複数回定義されているメソッドを呼び出さない限り実行できますが、M()メソッドを呼び出す限り、すぐに失敗します。次のことは、次のようなコマンドラインパラメーターです。
Javac誤って/*。Javajava-cp。:スレッドの間違ったC例外 "Main" Java.lang.incompatibleclasschangeerror:競合するデフォルトの方法:C.Main(C.Java:5)Java -cp。
結論は
デフォルトの実装をインターフェイスにJava 8環境に追加するクラスライブラリを移植すると、一般的に問題はありません。少なくともこれは、Java8クラスのライブラリ開発者がコレクションクラスにデフォルトのメソッドを追加するときに考えるものです。クラスライブラリを使用するアプリケーションは、デフォルトの方法なしでJava7のクラスライブラリに依存しています。複数の異なるクラスライブラリを使用および変更する場合、競合の可能性はわずかです。どうすればそれを避けることができますか?
以前のようにクラスライブラリを設計します。デフォルトのメソッドに頼ることができる場合は、軽視しないでください。絶対に必要なように使用しないでください。他のインターフェイスとの競合を避けるために、メソッド名を賢く選択します。 Javaプログラミングの開発にこの機能を使用する方法を学びます。
要約します
上記は、この記事のコンテンツ全体です。この記事の内容には、すべての人の研究や仕事に特定の参照値があることを願っています。ご質問がある場合は、メッセージを残してコミュニケーションをとることができます。 wulin.comへのご支援ありがとうございます。