函數式接口


函數式接口

1. 函數式接口定義

  • 一個接口有且只有一個抽象方法。
  • 函數式接口的實例可以通過 lambda 表達式、方法引用或者構造方法引用來創建。
注意:
  1. 如果一個接口只有一個抽象方法,那么該接口就是一個函數式接口
  2. 如果我們在某個接口上聲明了 @FunctionalInterface 注解,那么編譯器就會按照函數式接口的定義來要求該接口

函數式接口應滿足:

  • 該接口是一個接口類型而不是注解類型,枚舉類型或類類型
  • 被聲明 @FunctionalInterface 注解的接口應該滿足函數式接口的定義

如果不滿足上述條件,編譯器就會生成錯誤信息。

  1. 如果某個接口只有一個抽象方法,但我們並沒有給該接口聲明 @FunctionalInterface 注解,那么編譯器依舊會將該接口看作是函數式接口
重寫 Object 類里的方法不會導致函數式接口失效

​ 如果一個接口聲明了抽象方法,但該抽象方法重寫了 Object 類里的一個公有方法,那么對於 Java 編譯器來說,它並不會認為該方法符合函數式接口的抽象方法(即不把該方法當作函數式接口的抽象方法)。因為接口的實現類都會直接或間接繼承 Object 這個根類,所以在函數式接口中定義與 Object 類中簽名一樣的方法是不會導致函數式接口失效的。

舉例:

舉例的接口聲明為函數式接口,並重寫了 toString() 這個 Object() 方法,但是並不會報錯:

@FunctionalInterface
public interface MyInterface {

    void test();

    String toString();

}

2. 默認方法 default-method

jdk1.8 以后接口里面可以定義方法的實現,這種方法叫做 default-method。

舉例:

舉個例子:forEach方法

default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}

該實現方法定義在 Iterable 中。

3. 靜態方法 static-method

jdk1.8 后接口也可以定義靜態方法。

舉例:

public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
    return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
}

4. 使用 default method 注意

4.1 類實現接口方法

如果接口聲明了 default 方法,並且某類實現了該接口,那么 default 方法將會被繼承。

這里有個問題:

如果有一個類繼承了兩個不同接口的同名 default 方法,jvm 編譯器是無法識別到底該使用哪個方法的,必須重寫 default 方法,如下:

public class MyClass implements MyInterface1, MyInterface2 {
    @Override
    public void myMythod() {
        MyInterface2.super.myMethod();
    }
    
    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        myClass.myMethod();
    }
}

可以重寫也可以在重寫方法中指定要繼承接口的 default 方法。

4.2 子類繼承父類並實現接口

實現類的優先級比接口高。

public class MyClass extends MyInterfaceImpl implements MyInterface2 {
    
    public stativ void main(String[] args) {
        MyClass myClass = new MyClass();
        myClass.myMethod();
    }
    
}

MyInterfaceImpl 中有個和 MyInterface2 同名的 myMethod() 方法。

運行上述代碼,編譯器並不會報錯,因為實現類的優先級比接口高,所以 myClass.myMethod() 調用的方法默認是 MyInterfaceImpl 類中的實現方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM