簡體   English   中英

為什么我們不能在功能界面中重載抽象方法? (JAVA)

[英]Why can't we overload a abstract method in a functional interface? (Java)

所以我熟悉java中的函數接口,以及它們與lambda表達式的使用。 功能界面只能包含一個抽象方法。 當從lambda表達式中使用這個孤獨的方法時,您不需要指定它的名稱 - 因為接口中只有一個抽象方法,編譯器知道這是您引用的方法。

例:

// Functional Interface:

@FunctionalInterface
public interface Ball
{
    void hit();
}

// Lambda to define, then run the hit method:

Ball b = () -> System.out.println("You hit it!");

b.hit();

雖然很明顯為什么功能接口只能包含一個抽象方法,但我不明白為什么不能重載該方法。

例如,以下內容將無法編譯:

// (NOT) Functional Interface:

@FunctionalInterface
public interface Ball
{
    void hit();
    void hit(boolean miss);
}

// Lambda to define, then run the hit method:

Ball b = () -> System.out.println("You hit it!");
Ball ba = (boolean miss) -> System.out.println(miss);

b.hit();
ba.hit(false);

編譯器聲明Ball接口不起作用,因為它包含多個方法,但在這種情況下我不明白為什么這會是一個問題 - 只要兩個方法采用不同的參數,就應該可以推斷出哪個方法我根據我定義的參數在lambda中引用。

有人可以解釋為什么不能在功能界面中重載抽象方法嗎?

在沒有方法重載的語言中,方法由它們在該類中的名稱唯一標識(暫時忽略覆蓋)。

在Java中,事情有點不同。 引用oracle文檔

重載方法

Java編程語言支持重載方法,Java可以區分具有不同方法簽名的方法。 這意味着如果類中的方法具有不同的參數列表,則它們可以具有相同的名稱(有一些資格,將在標題為“接口和繼承”的課程中討論)。

所以我們知道方法也通過它們的簽名來識別。 如果兩個方法共享一個名稱但沒有相同的簽名,則它們是不同的方法 不要讓他們的共同名稱欺騙你認為他們有某種關聯。

考慮到這一事實,我們可以輕松地創建一個示例,如果方法按照您描述的方式運行,則會發生未定義的行為:

Ball ba = (boolean miss) -> System.out.println(miss);
someFunction(ba)
public void someFunction(Ball ball) {
    ball.hit();
}

在這種情況下你會期待什么行為? 它是未定義的!


但是,您可以使用默認方法 我不太了解你的情況,以判斷這是否合適,但你可以這樣做:

@FunctionalInterface
public interface Ball
{
    default void hit() {
        hit(true);
    }

    void hit(boolean miss);
}

為什么這個工作在FunctionalInterface文檔中解釋:

從概念上講,功能界面只有一種抽象方法。 由於默認方法具有實現,因此它們不是抽象的

只要您聲明一個實現Ball接口的類,就必須實現所有抽象方法。 例如,如果你這樣做:

Ball b = () -> System.out.println("You hit it!");

然后你傳遞b作為參數,而其他代碼調用b.hit(true) ,它會粉碎,因為沒有實現hit(boolean miss)

因此功能接口必須只有一個抽象方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM