Java 8には、 Defenderメソッド と呼ばれる新機能が含まれています。これにより、インターフェースにデフォルトのメソッド実装を作成できます。
まず第一に、これはJavaのすべての凝縮されたプログラマーにとって大きなパラダイムシフトです。私は、Brain GoetzによるJavaOne 13のプレゼンテーションを見ました。彼は、コレクションライブラリの新しいstream()
およびparallelStream()
実装について話し合っていました。
Collection
インターフェースに新しいメソッドを追加する場合、以前のバージョンを壊さずに新しいメソッドを追加することはできませんでした。そのため、これに対応するために、Defaultメソッドの新機能が追加されたと彼は言いました。
public interface SimpleInterface {
public void doSomeWork();
//A default method in the interface created using "default" keyword
default public void doSomeOtherWork(){
System.out.println("DoSomeOtherWork implementation in the interface");
}
}
今私の質問は基本的には、クライアントコードを壊すことなくインターフェイスに新しいメソッドを追加する必要があるときに、デフォルトのメソッドが役立つことですか?それとも他の用途もありますか?
将来のバージョンでインターフェースにメソッドを追加する可能性があることに加えて、interface
が機能的なインターフェースを維持できるようにする重要なポイントがあります複数のメソッドがある場合でも。
関数型インターフェースには、ラムダ式を介して実装できるデフォルト以外の抽象メソッドが1つだけあります。 1つの例は the Predicate
interface で、抽象メソッド(test
)が1つだけありますが、Predicate
を無効にするか、別のメソッドと組み合わせるためのデフォルトのメソッドを提供しますPredicate
。デフォルトのメソッドがない場合、これらのメソッドはJava 8より前のCollections
クラスなどの別のユーティリティクラスで提供する必要がありました(そのようなinterface
のラムダ実装の可能性を放棄したくないため) )。
あなたが言ったように、主な動機は既存のインターフェースの進化を可能にしていました。
ただし新しいインターフェースでも使用したい理由があります。
そのような理由の1つは、インターフェースの他の(デフォルト以外の)メソッドを使用して簡単に実装できるメソッドです。これにdefault
メソッドを使用すると、Foo
- interface/AbstractFoo
- base-implementationの組み合わせの必要性が減少します(例:AbstractList
を参照)。
これによって完全に新しいフィールドが作成されるわけではありませんが、実装が簡単なまま、エンドユーザーフレンドリーなインターフェース(便利なメソッドがたくさんあります)を使用できることを意味します。
拡張に対応していないインターフェースに問題がありました。つまり、インターフェースに新しいメソッドを追加する必要がある場合、これらのインターフェースの既存の実装が壊れていました。したがって、メソッドが必要ない場合でも、そのインターフェイスを実装するすべてのクラスが、新しく追加されたメソッドの実装を提供する必要がありました。したがって、インターフェースの進化は容易ではありませんでした。
頭に浮かぶ1つの例は、Java MapReduce API for Hadoopです。これは0.20.0リリースで変更され、インターフェースよりも抽象クラスを優先するようになりました。進化するのが簡単だからです。つまり、新しいメソッドです。クラスの古い実装を壊すことなく、(デフォルトの実装で)抽象クラスに追加できます。
Java 8のリリースにより、インターフェースにもデフォルトのメソッドを追加できるようになりました。これにより、それらも簡単に進化させることができます。インターフェースにデフォルトのメソッドを追加すると、新しいメソッドが追加されます。 、インターフェイスであっても、既存のコードが破損することはありません。