[英]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.