Effective Java讀書筆記-接口優於抽象類

抽象類與接口的區別:

  1. 抽象類中可以有已經實現的方法,接口中只能存放方法的定義。
  2. 爲實現抽象類定義的類型,類必須繼承抽象類。

現有的類很容易被更新,以實現接口

當類需要添加新的方法時,最好的辦法就是定義一個接口讓類去實現它。注意無法通過更新現有的類來拓展抽象類。如果有兩個類都需要實現這個抽象類中的方法時,最好的辦法就是將這個抽象類放在更高的層次上,定義一個類去實現這個抽象類。之後讓這兩個類去繼承這個類。但是這會帶來層次上的問題。這兩個類的後代都必須繼承這個抽象類,無論合適不合適。

接口是定義mixin類型的理想選擇

類除了實現它的基本類型之外還可以通過mixin類型來實現一些拓展功能。Comparable就是一種mixin類型。這類接口之所以被稱爲mixin類型主要是因爲它定義的功能可以拓展到類的主要功能中。抽象類不能用於定義mixin,主要是因爲它不能拓展到主要的類中。

接口允許我們構造非層次框架的類型框架

比如有兩個類:

//歌唱者類
public interface singer{
    AudioClip Sing(Song s);
}

//創作者類
public interface SongWriter{
    Song compose(boolean hit)
}

很多歌唱者也許會是創作者。如果它們都是抽象類,讓第三方(抽象類)去繼承它們。顯然是不可能的。但如果它們都是接口這是完全可以的。注意這裏會有“組合爆炸”的問題。如果需要繼承n個方法,該抽象類需要繼承n個接口,這n個接口會有2^n種組合,這會造成類層次上的臃腫進而造成類的臃腫。這就是“組合爆炸”現象。

接口可以通過包裝類模式來提高安全性,而抽象類只能通過繼承來拓展功能,因此從安全性上來說抽象類不如接口。

每個接口都有一個抽象的骨架實現類(skeletal implementation),接口的作用是定義方法,抽象骨架實現類的方式是實現接口中定義的方法。抽象骨架實現類很好的將接口與抽象類的優點結合在了一起。骨架實現被稱爲AbstractInterface。

骨架實現類的好處它在實現抽象類上提供了幫助,但並沒有在抽象類型作爲定義上提供明顯的限制。對於大多數的接口來說實現骨架接口是一個顯然的選擇,並不是一定的。

使用抽象類的一大好處是可以用來實現多個類型。與實現接口相比抽象類有一個很明顯的優勢:抽象類的演化比接口要容易的多。如果在後續發行的版本中,如果你希望在抽象類中添加新的方法,始終可以增加具體的方法,它包含合理的默認實現。然後抽象類的所有實現都將實現這個新的方法。對於接口,這樣做是行不通的。

要想在公共接口中增加方法,並且不去破壞實現這個接口的所有現有的類,這是不可能的。之前實現該接口的類將會漏掉新增加的方法,並且無法再通過編譯。在爲接口增加新方法的同時,也爲骨架實現類增加同樣的新的方法,這樣可以在一定程度上減小由此帶來的破壞。

*注意:接口一旦被公開發行,並且被廣泛的使用,再想改變這個接口幾乎是不可能的了。

  • 當演變的容易性比靈活性更爲重要時,應當使用抽象類來定義類型。
  • 如果導入了一個重要的接口,就應該考慮同時提供骨架實現類。
  • 儘可能謹慎的設計所有的公共接口,並編寫多個實例對它們進行全面的測試。
發佈了78 篇原創文章 · 獲贊 6 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章