默认方法和多重继承
最近盧卡斯JOOQ埃德爾發布和文章有關嵌套類及其使用。 這是一個有趣的話題,他的文章一如既往地有趣并且值得一讀。 我只同意一個簡短的聲明,我們有一個簡短的回復鏈,導致默認方法,以及為什么不能有類似的東西
在Java中。 可以這么說,在上面的代碼中,內部接口的默認方法將引用包圍該接口的實例。 我認為“答復”不是最佳的溝通方式,因為最初的話題有所不同,我現在就去談談。
什么是默認方法
你可能知道。 如果不是google,或者閱讀我的文章Java 8默認方法:可以做什么和不能做什么? 以及如何不使用Java 8默認方法 。
如果您用谷歌搜索,您會發現Java 8中的默認方法帶來了迦南語,多重繼承是可用的。
與真正了解Java的專業人士在stackoverflow上進行了很好的討論:
Java一直具有類型的多重繼承。 默認方法增加了行為的多重繼承,但沒有狀態的多重繼承。 (大多數麻煩源于C ++等語言中狀態的多重繼承。)– Brian Goetz 2014年 6月21日,2:05
在本文中,我將研究如何解釋和理解該聲明。
繼承類型
Brian Goetz的話中提到:
- 類型的繼承
- 行為的繼承,以及
- 國家的繼承。
類型的繼承非常容易,并且對于Java程序員是眾所周知的。 您可以在接口中定義抽象方法,但不指定抽象方法的工作方式,而僅指定方法的返回值和簽名。 Java 8使用默認方法引入了行為繼承而不是狀態繼承。 但是,您是否真的可以擁有行為繼承而不擁有狀態繼承呢? 并不是的。 至少在Java 8中,您可以繼承狀態,盡管不建議這樣做,它的執行效果不佳(我的意思是:它可能很慢),而且程序繁瑣且容易出錯。 但是可以,我將在這里展示如何操作。 (除了我在上面提到的文章中發布的線程本地廢話之外。)
我相信Java 8發明者希望使用默認方法在標準運行時實現功能接口(例如流)時保持向后兼容性。 最近,我觀看了Fargo系列,我覺得語言設計師對問題“是您真正想要的嗎?”的回答是“是”。
使用默認方法進行狀態繼承
默認方法無法訪問字段(靜態字段除外,靜態字段無論如何在接口中都是最終的,因此讓我們暫時忘記它們)。 就像您無法從擴展了A的B類訪問A類的私有字段一樣。反之亦然:您無法從A訪問B的私有字段。但是,您可以在B中擁有getter和setter,如果您聲明了它們作為A中的抽象方法,您可以獲得訪問權限。 芝麻開門。 Getter和Setters是解決方案。
在接口中為要從默認方法訪問的所有狀態字段聲明抽象方法時,可以訪問它們。 這樣,您將獲得與真實狀態繼承相同的結果。 區別在于語法:您使用getter和setter方法而不是字段名稱,并且必須在接口中聲明這些方法。 通過這種方式,編譯階段會檢查getter和setter是否確實存在。
您會看到Java 8的情況變得非常復雜。 將其與泛型混合使用,您可能找不到一個了解這一切的鮮活靈魂。 有一個結構,像
Outer.this.toString()上面的示例代碼中的代碼可能會使它變得更加復雜,而沒有實際的杠桿作用。
我相信我對Java 8中的默認方法以及如何使用它們有一定的了解。 但是,擁有10年Java和30年以上編程經驗的經驗不足以讓我知道應該如何使用默認方法。 對于仍在生產代碼中使用Java 1.6或更早版本的開發人員,我感到嫉妒:他們不必擔心默認方法。 (這只是個玩笑。)
即使我嘗試提供一些建議。
建議
切勿在默認方法中模仿狀態繼承。 雖然很難說出它在實踐中是什么。 調用getter或setter顯然是。 調用在實現類中實現的某些抽象方法可能會也可能不會。 如有疑問:最好不要。
永遠不要使用我在另一篇文章中寫的threadlocal技巧。
對于Java語言發明者使用的默認方法,使用默認方法:在庫接口中保持向后兼容性。 如果您曾經發布過一個庫并且它包含一個接口(否則,順便說一句), 請不要對其進行更改...請考慮使用實現該接口的庫來考慮客戶端代碼。 在Java 8中,您可以完成以下句子: 不要將其更改為不兼容的。 如果有一個新方法:創建一個默認實現,這樣已經實現了先前版本的代碼將保持兼容,并且無需擴展這些類。
翻譯自: https://www.javacodegeeks.com/2015/02/default-methods-multiple-inheritance.html
總結
- 上一篇: 针对Java中的XSD验证XML
- 下一篇: 台式电脑可以当显卡坞吗(显卡坞能装什么显