78

最近、Java 8の調査を開始しましたが、Javaによるラムダ式の実装に不可欠な「関数型インターフェース」の概念を完全に理解することはできません。Javaのラムダ関数に関するかなり包括的なガイドがありますが、機能インターフェイスの概念を定義する章に行き詰まりました。定義は次のとおりです。

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

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

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

Comparator引数の代わりにラムダ関数を使用できることをテストできました(つまりCollections.sort(list, (a, b) -> a-b))。

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

4

8 に答える 8

71

リンクした同じページから

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

私はそれを本当によく言うことはできません。

于 2013-02-01T22:25:14.783 に答える
15

別の説明は@FunctionalInterfaceページにあります:

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

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

例えば:

  • これは動作します

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

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

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

于 2016-02-23T09:54:49.367 に答える
3

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

A。

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

于 2016-02-20T11:10:35.380 に答える
1

関数型インターフェースには1つの抽象メソッドしかありませんが、複数のデフォルトメソッドと静的メソッドを持つことができます。

デフォルトのメソッドは抽象的ではないため、機能インターフェイスにデフォルトのメソッドを好きなだけ追加できます。

@FunctionalInterface
public interface MyFuctionalInterface 
{
public void perform();

default void perform1(){
//Method body
}

default void perform2(){
//Method body
}
}

インターフェイスがのパブリックメソッドの1つをオーバーライドする抽象メソッドを宣言する場合、インターフェイスの実装には他の場所java.lang.Objectからの実装があるため、インターフェイスの抽象メソッドカウントにもカウントされませんjava.lang.Object

コンパレータは、2つの抽象メソッドを宣言していても、機能的なインターフェイスです。これらの抽象メソッドの1つ「<code>equals()」は、Objectクラスのパブリックメソッドと等しいシグネチャを持っているためです。たとえば、以下のインターフェースは有効な機能インターフェースです。

@FunctionalInterface
    public interface MyFuctionalInterface 
    {
    public void perform();
 
    @Override
    public String toString();                //Overridden from Object class
 
    @Override
    public boolean equals(Object obj);        //Overridden from Object class
    }
于 2020-07-03T12:16:28.867 に答える
1

インターフェイスにはパブリックメソッドと抽象メソッドが必要なため、インターフェイスはObjectクラスを拡張できません。

Objectクラスのすべてのパブリックメソッドには、インターフェイスに暗黙のパブリックメソッドと抽象メソッドがあります。

これは、次のように記述されている標準のJava言語仕様です。

「インターフェイスに直接スーパーインターフェイスがない場合、インターフェイスは、シグネチャs、リターンタイプrを使用してパブリック抽象メンバーメソッドmを暗黙的に宣言し、シグネチャs、リターンタイプrを使用して各パブリックインスタンスメソッドmに対応する句tをスローし、スローします。同じシグニチャ、同じreturnタイプ、および互換性のあるthrows句を持つメソッドがインターフェイスによって明示的に宣言されていない限り、オブジェクトで宣言された句t。」</ p>

これが、オブジェクトクラスのメソッドがインターフェイスで宣言される方法です。また、JLSによると、これはインターフェースの抽象メソッドとしてカウントされません。したがって、コンパレータインターフェイスは機能的なインターフェイスです。

于 2021-05-29T15:08:52.893 に答える
-1

Javaドキュメントによると:

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

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

インターフェイスで宣言されたすべてのメソッドは抽象的であると思いました(つまり、デフォルトの実装はありません)。しかし、多分私は何かが欠けています。

于 2013-02-01T22:19:54.257 に答える
-1

意味:

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

使用法:

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

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

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

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

  1. Runnable:run()メソッドのみが含まれます。
  2. 呼び出し可能:call()メソッドのみが含まれます。
  3. 比較可能:compareTo()メソッドのみが含まれます。
于 2017-12-06T13:24:55.593 に答える
-1

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

だから問題は、機能インターフェイスとは何ですか?シングルアブストラクトメソッド(SAM)を使用するインターフェイスは、機能インターフェイスと呼ばれます。

つまり-

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

サンプルコードhttps://readtorakesh.com/functional-interface-java8/で詳細を確認してください

于 2018-08-11T17:16:46.147 に答える