web-dev-qa-db-ja.com

Java 8での「機能インターフェース」の正確な定義

最近私はJava= 8を調査し始めましたが、ラムダ式のJavaの実装に不可欠な「関数型インターフェース」の概念を完全に理解できません。 かなり包括的なguide をJavaのラムダ関数に追加しましたが、 関数インターフェイスの概念を定義する章に行き詰まりました

より正確には、機能インターフェースは、抽象メソッドを1つだけ持つインターフェースとして定義されます。

次に、彼は例に進みます。その1つがComparatorインターフェースです。

_public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
} 
_

コンパレーターの引数の代わりにラムダ関数を使用できることをテストでき、機能します(つまり、Collections.sort(list, (a, b) -> a-b))。

ただし、Comparatorインターフェースでは、compareメソッドとequalsメソッドの両方が抽象です。つまり、2つの抽象メソッドを持っています。では、定義でインターフェイスに正確に1つの抽象メソッドが必要な場合、これはどのように機能しますか?ここで何が欠けていますか?

66

リンク先と同じページ から:

インターフェースComparatorは、2つの抽象メソッドを宣言していますが、そのうちの1つ(等しい)はObjectのパブリックメソッドに対応するシグネチャを持っているため、機能的です。インターフェイスは常にObjectのパブリックメソッドに対応する抽象メソッドを宣言しますが、通常は暗黙的に宣言します。暗黙的または明示的に宣言されているかどうかにかかわらず、そのようなメソッドはカウントから除外されます。

私はそれをもっとよく言うことはできません。

編集:モーリスのコメントに従って、このページの最新のテキストに更新しました(ありがとう!)

56
Mark Peters

@ FunctionalInterfaceページ に別の説明があります。

概念的には、関数型インターフェースには1つの抽象メソッドしかありません。デフォルトのメソッドには実装があるため、抽象メソッドではありません。 インターフェイスがJava.lang.Objectのパブリックメソッドの1つをオーバーライドする抽象メソッドを宣言する場合、インターフェイスの実装にはJava.lang.Objectまたは他の場所からの実装があるため、インターフェイスの抽象メソッド数にはカウントされません。

@FunctionalInterfaceを使用して、どのインターフェースが正しい機能インターフェースかをテストできます。

例えば。:

  • これは機能します

    @FunctionalInterface
    public interface FunctionalInterf {
    
        void m();
    
        boolean equals(Object o);
    
    }
    
  • これはエラーを生成します:

    @FunctionalInterface
    public interface FunctionalInterf {
    
        void m();
    
        boolean equals();
    
    }
    

    インターフェースFunctionalInterfにある複数のオーバーライドしない抽象メソッド

7

Q.しかし、Comparatorインターフェースでは、compare()メソッドとequals()メソッドの両方が抽象的です。つまり、2つの抽象メソッドがあります。では、定義でインターフェイスが1つだけの抽象メソッドを持つ必要がある場合、これはどのように機能しますか?ここで何が欠けていますか?

A.

関数型インターフェイスは、「関数型インターフェイス」のステータスに影響を与えることなく、equals()などのObjectで定義されたパブリックメソッドを指定できます。パブリックオブジェクトメソッドは、機能インターフェイスのインスタンスによって自動的に実装されるため、機能インターフェイスの暗黙のメンバーと見なされます。

3
Aniket Thakur

Java docsは言う:

Object.equals(Object)をオーバーライドしないことが常に安全であることに注意してください。ただし、このメソッドをオーバーライドすると、2つの異なるコンパレーターが同じ順序を課していることをプログラムが判断できるようになり、パフォーマンスが向上する場合があります。

多分コンパレータは特別ですか?たぶん、それがインターフェースであるとしても、equals()を呼び出すcompare()のデフォルト実装がどういうわけか存在しますか?アルゴリズム的には、それは取るに足らないことです。

インターフェイスで宣言されたすべてのメソッドは抽象的である(つまり、デフォルトの実装がない)と思いました。しかし、おそらく何かが足りない。

0
Seva Alekseyev

定義:

インターフェースに抽象メソッドが1つだけ含まれている場合、そのようなタイプのインターフェースは機能インターフェースと呼ばれます。

用途:

  1. Lambda式 "->"を記述してその機能を呼び出したら、このコンテキストでは、Functional Interfaceが必要です。
  2. Lambda式を参照するには、Functional Interfaceリファレンスを使用できます。
  3. 関数型インターフェースの内部には、1つの抽象メソッドとn個のデフォルト/静的メソッドを含めることができます。

継承に関する機能インターフェース:

インターフェースが機能インターフェースを拡張し、子インターフェースに抽象メソッドが含まれていない場合、子インターフェースも機能インターフェースと見なされます。

機能インターフェースはJavaにとって新しいものではなく、次のインターフェースAPIですでに使用されています:

  1. Runnable:run()メソッドのみが含まれます。
  2. Callable:call()メソッドのみが含まれます。
  3. 比較可能:compareTo()メソッドのみが含まれます。
0

Java 8より前は、インターフェイスは、抽象メソッドとも呼ばれる1つ以上のメソッド(実装のないメソッドで、シグニチャのみ)のみを宣言できました。 Java 8以降、インターフェースは1つ以上のメソッド(インターフェースのデフォルトメソッドとも呼ばれます)と静的メソッド、および抽象メソッドの実装を持つこともできます。インターフェイスのデフォルトメソッドは、デフォルトキーワードとしてマークされています。

問題は、機能的インターフェースとは何かということです。単一抽象メソッド(SAM)を持つインターフェースは、機能インターフェースと呼ばれます。

つまり-

  1. 単一の抽象メソッドを持つインターフェースは機能インターフェースです
  2. 単一抽象メソッドと0個以上のデフォルトメソッドおよび0個以上の静的メソッドを備えたインターフェースも有効な機能インターフェースです。

コード例の詳細 https://readtorakesh.blogspot.com/2018/08/functional-interface-Java8.html

0