我對 Java 有點熟悉,并且在 Effective Java(2017) 中遇到了一些對我來說沒有多大意義的東西。
下面是書中的一段。(第 18 項)
與方法呼叫不同,繼承違反了封裝。換句話說,子類的正確功能取決于其超類的實作細節。超類的實作可能會隨著版本的變化而變化,如果發生這種情況,子類可能會中斷,即使它的代碼沒有被觸及。因此,一個子類必須與它的超類一起發展,除非超類的作者為了擴展的目的專門設計和記錄了它。
我理解在某些情況下組合可能比繼承更受青睞,并且理解了第 18 項的其他部分。但是,我發現很難理解組合方法如何防止上面段落中提到的問題(依賴于實作細節)——正如作者所說就好像因為這個原因,組合比繼承更好。在本章的后面,Bloch 給出了一個自定義 Set 實作的示例,其中他使用了 a Forwarding Class(這顯然依賴于 Set 介面細節)。有人可能會爭辯說 Set 介面不會經常更改,但實際上介面的更改也可能導致Wrapper Class中斷(注意本書通過轉發類和包裝類提供了一個示例)。
我想如果 Bloch 的意思是組合比繼承更安全,那是有道理的,因為類實作比介面更頻繁地更改。但是,我認為 Wrapper Class 和 Interface 之間仍然存在依賴問題,并且對作者為什么沒有更清楚地提及這一點感到困惑。
我這樣想是不是錯了?
(此外,我不確定封裝與此有什么關系。我對封裝的理解是使用私有隱藏變數..)
uj5u.com熱心網友回復:
您實際上應該提供更多關于示例的資訊,即“本章后面,Bloch 給出了一個自定義 Set 實作的示例”
基本上繼承是子類會受到父類變化的影響。請參見下面的代碼:
public class Baby extends Human{
}
在上面的代碼中,如果 Human 實作了另一個 public 或 protected 方法,Baby 將被迫自動繼承它。這是相當嚴格的。
但是對于組合而言,所有者物件的更改實際上并不需要子物件的更改,反之亦然。
public class Human{
private Baby baby;
}
在上面的代碼中,Human 可以有任何可能不會影響 Baby 的實作,反之亦然。設計嬰兒和人類可以做的事情有更多的余地。它們可以完全具有許多不同的屬性和方法。
uj5u.com熱心網友回復:
好的,所以我查看了@LeiYang 推薦的內容,并意識到我的問題無效。給定的段落指出“子類取決于其超類的實作細節以獲得適當的功能” - 物件組合不會有任何問題,因為它只是按原樣使用提供的方法(沒有覆寫)。因此Object Composition不違反封裝,相對于Inheritance.
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/428614.html
上一篇:抽象類java繼承
下一篇:為什么Java記錄不支持繼承?
