関数インターフェースは、「安全な」多重継承で使用されます。違い:
- クラスは、複数の機能インターフェースを拡張できます。
- 機能インターフェースは、抽象メソッドを 1 つだけ持つことができます。
- 関数型インターフェイスには、C++ 抽象クラスとは異なり、フィールドがない場合があります。
典型的な使用法は、デフォルトの機能をオブジェクトに組み込みたい場合です。つまり、関数のようなオブジェクトがある場合、
class MyFunction1 {
public Integer apply(String s){
...
}
}
class MyFunction2 {
public List<String> apply(Integer s){
...
}
}
そして、それらから構成を作成したい場合は、立ち寄るだけですimplements Function
:
class MyFunction1 implements Function<String, Integer>{
public Integer apply(String s){
...
}
}
class MyFunction2 implements Function<Integer, List<String>>{
public List<String> apply(Integer s){
...
}
}
また、関数の構成を作成することもできます。比較された 2 つのアプローチ:
機能インターフェースなし:
MyFunction1 myFunction1 = ...;
MyFunction2 myFunction2 = ...;
Function<String, List<String>> composition = (s) -> myFunction2.apply(myFunction1.apply(s));
機能的なインターフェースを使用:
MyFunction1 myFunction1 = ...;
MyFunction2 myFunction2 = ...;
Function<String, List<String>> composition = myFunction1.andThen(myFunction2);
違い
- 関数を再実装する必要はありません。
- 拡張クラスで使用できるその他の機能
compose
:およびidentity
.
- 新しいデフォルト関数はクラス階層の一部になり、新しいオブジェクトを作成する必要はありません。通常、次のような関数
compose()
は、クラスのサイズが大きくなるため、クラス定義に含まれません。多くの場合、それらは別個のユーティリティ クラスに入れられます。Functions
Guava では、コンポジションは別のユーティリティ クラス、Functions.composeに入れられます。したがって、新しい関数インターフェイスを使用すると、関数がどのユーティリティ クラスに実装されているかを思い出す必要がなくなります。