3 回答

TA貢獻(xiàn)1797條經(jīng)驗(yàn) 獲得超4個(gè)贊
Father這里不是問(wèn)題,因?yàn)閬?lái)自接口的靜態(tài)方法不是繼承的(例如List.of(..)不能通過(guò)調(diào)用ArrayList.of(..))所以沒(méi)有覆蓋/隱藏,這也意味著沒(méi)有沖突。
因此我們可以安全地寫
interface Father {
static void method() { }
}
interface Child extends Father {
static void method() { }
}
問(wèn)題是繼承default void method() { }自接口的方法,這意味著之后MotherChild
interface Child extends Father, Mother {
static void method() { }
}
你最終會(huì)得到有兩個(gè)method()版本的接口:靜態(tài)和非靜態(tài)(默認(rèn))
interface Child extends Father, Mother {
static void method() { }
default void method() { } //inherited from Mother
}
但為什么這是個(gè)問(wèn)題?
假設(shè)您想向Child接口添加另一個(gè)方法,該方法將調(diào)用method()
interface Child extends Father, Mother {
static void method() { }
default void method() { } //inherited from Mother
default void demo(){
method(); //which code block should be executed?
}
}
它應(yīng)該從靜態(tài)方法() 還是從默認(rèn)方法() 執(zhí)行代碼?編譯器將無(wú)法決定。
雖然這種情況可以通過(guò)使用來(lái)解決
Child.method()對(duì)于靜態(tài)方法,
this.method()對(duì)于默認(rèn)方法(是的,它不會(huì)有歧義,因?yàn)殪o態(tài)方法不會(huì)this被實(shí)例化的類繼承),
重點(diǎn)是首先要防止此類問(wèn)題。這就是為什么我們被要求不能在一個(gè)地方(定義或繼承)具有相同簽名(名稱+參數(shù)類型)的靜態(tài)和非靜態(tài)方法。

TA貢獻(xiàn)2019條經(jīng)驗(yàn) 獲得超9個(gè)贊
這是一個(gè)有趣的情況。我認(rèn)為簡(jiǎn)單的答案是靜態(tài)方法從未被允許隱藏(它們不能覆蓋)基類中的非靜態(tài)方法。如果您static
從 中刪除修飾符Father
,那也會(huì)導(dǎo)致 Child 無(wú)法編譯。這可能是為了避免混淆。
所以默認(rèn)方法只是遵循現(xiàn)有規(guī)則。
“但是等一下”,您可能會(huì)想,“添加默認(rèn)方法的目的是明確允許庫(kù)開(kāi)發(fā)人員在不破壞現(xiàn)有代碼的情況下將新功能引入舊接口。如果任何現(xiàn)有代碼具有名稱沖突的靜態(tài)方法 - 不會(huì)它壞了?”
其實(shí)我覺(jué)得不一定。IIRC,這是一個(gè)有意允許二進(jìn)制兼容性和源兼容性不同的地方。我想你會(huì)發(fā)現(xiàn)如果:
interface Child
(和使用它的東西)已經(jīng)被編譯,而默認(rèn)方法不存在于interface Mother
, 和您稍后將默認(rèn)方法添加到該源文件并僅
interface Mother
編譯該源文件。
然后我認(rèn)為你最終會(huì)得到工作正常的代碼(在字節(jié)碼/JVM 級(jí)別)。但是,它會(huì)在您嘗試針對(duì) interface Child
更新的interface Mother
.

TA貢獻(xiàn)1847條經(jīng)驗(yàn) 獲得超11個(gè)贊