97

Collection Interface で、removeIf()その実装を含むという名前のメソッドを見つけました。

default boolean removeIf(Predicate<? super E> filter) {
    Objects.requireNonNull(filter);  
    boolean removed = false;  
    final Iterator<E> each = iterator();   
    while (each.hasNext()) {  
        if (filter.test(each.next())) {  
            each.remove();  
            removed = true;  
        }  
    }  
    return removed;  
}  

インターフェイスでメソッド本体を定義する方法があるかどうか知りたいですか? キーワードと
は何ですか?default

4

3 に答える 3

170

https://dzone.com/articles/interface-default-methods-javaより

Java 8 では、「デフォルト メソッド」または (Defender メソッド) の新機能が導入されています。これにより、開発者は、これらのインターフェイスの既存の実装を壊すことなく、インターフェイスに新しいメソッドを追加できます。具象クラスがそのメソッドの実装を提供できない状況でデフォルトとして使用されるインターフェイス定義の実装を許可する柔軟性を提供します。

public interface A {
    default void foo(){
       System.out.println("Calling A.foo()");
    }
}

public class ClassAB implements A {
}

新しい機能について初めて聞いたときに、デフォルトのメソッドについてよくある質問が 1 つあります。

クラスが 2 つのインターフェイスを実装し、それらの両方のインターフェイスが同じシグネチャを持つデフォルト メソッドを定義する場合はどうなるでしょうか。

この状況を説明する例:

public interface A {  
    default void foo(){  
        System.out.println("Calling A.foo()");  
    }  
}

public interface B {
    default void foo(){
        System.out.println("Calling B.foo()");
    }
}


public class ClassAB implements A, B {

}  

このコードは、次の結果でコンパイルに失敗します。

java: class Clazz inherits unrelated defaults for foo() from types A and B

これを修正するには、Clazz で競合するメソッドをオーバーライドして手動で解決する必要があります。

public class Clazz implements A, B {
    public void foo(){}
}

しかし、独自のメソッドを実装する代わりに、インタフェース A からメソッド foo() のデフォルトの実装を呼び出したい場合はどうでしょう。

次のように A#foo() を参照することができます。

public class Clazz implements A, B {
    public void foo(){
       A.super.foo();
    }
}
于 2013-08-17T08:57:12.987 に答える
51

これらのメソッドは、デフォルト メソッドと呼ばれます。Default メソッドまたはDefender メソッドは、Java 8 で新しく追加された機能の 1 つです。

これらは、具象クラスがそのメソッドの実装を提供しない場合に、インターフェイス メソッドがデフォルトとして使用される実装を提供できるようにするために使用されます。

したがって、デフォルトのメソッドを使用するインターフェースがある場合:

public interface Hello {
    default void sayHello() {
        System.out.println("Hello");
    }
}

次のクラスは完全に有効です。

public class HelloImpl implements Hello {

}

のインスタンスを作成する場合HelloImpl:

Hello hello = new HelloImpl();
hello.sayHello();  // This will invoke the default method in interface

便利なリンク:

于 2013-08-17T07:24:04.977 に答える
17

少し調べてみたところ、以下のことがわかりました。お役に立てれば。

既存の問題

通常のインターフェイス メソッドは抽象として宣言され、インターフェイスを実装するクラスで定義する必要があります。これにより、宣言されたすべてのメソッドを実装する責任がクラス実装者に「負担」になります。さらに重要なことに、これは「公開」後にインターフェースを拡張できないことも意味します。そうしないと、すべての実装者が実装を調整する必要があり、ソースとバイナリの下位互換性が失われます。

Java 8 で採用されたソリューション

これらの問題に対処するために、JDK 8 の新機能の 1 つは、既存のインターフェースをデフォルトのメソッドで拡張できる機能です。デフォルトのメソッドは、宣言されるだけでなく、インターフェイスでも定義されます。

重要な注意事項

  1. 実装者は、実装クラスでデフォルト メソッドを実装しないことを選択できます。
  2. 通常の非 final クラス メソッドをサブクラスでオーバーライドできるように、実装者は引き続きデフォルト メソッドをオーバーライドできます。
  3. 抽象クラスは、デフォルトのメソッドを抽象として (再) 宣言することもでき、サブクラスにメソッドの再実装を強制します (「再抽象化」と呼ばれることもあります)。
于 2013-08-17T07:46:21.293 に答える