整理 Effective Java 書中 Item 23: Prefer class hierarchies to tagged classes 心得筆記
主旨
在寫Java時,有時我們會想設計一個類別,可以代表「好幾種不同型態的物件」。這時,有些人會選擇用一個「tag 欄位」來做判斷,稱為 tagged class。但這樣的寫法其實有很多問題,本條目會說明為什麼應該用「類別階層」來取代「tagged class」。
🧨 什麼是 Tagged Class?
來看一個實際範例:
整理 Effective Java 書中 Item 23: Prefer class hierarchies to tagged classes 心得筆記
在寫Java時,有時我們會想設計一個類別,可以代表「好幾種不同型態的物件」。這時,有些人會選擇用一個「tag 欄位」來做判斷,稱為 tagged class。但這樣的寫法其實有很多問題,本條目會說明為什麼應該用「類別階層」來取代「tagged class」。
來看一個實際範例:
整理 Effective Java 書中 Item 22: Prefer interfaces to abstract classes 心得筆記
Java 的介面(interface)本質是用來定義「型別」的 —— 換句話說,介面要描述的是「這個物件可以做什麼」。如果你只是想要存一些常數,卻用介面來達成,那麼你就誤用了這個語言工具。
整理 Effective Java 書中 Item 21: Design interfaces for multiple inheritance 心得筆記
Java 8 引入了 default method
,終於讓介面可以新增方法而不會立刻讓現有的實作壞掉。但這個看似萬能的解法,其實潛藏不少風險,特別是對原本沒設計來支援這些方法的舊實作。這篇提醒你:設計介面時最好一開始就想清楚,因為事後「加東西」很可能會讓系統爆炸。
在 Java 8 之前,介面一旦公開出去,就幾乎不能再改。加一個新方法,所有實作都會爆錯。default method
的出現,讓我們「表面上」可以擴充介面,不用動到原本的實作。
整理 Effective Java 書中 Item 20: Prefer interfaces to abstract classes 心得筆記
Java 提供兩種方式定義「可以有多個實作」的類型:介面(interface)和抽象類別(abstract class)。在 Java 8 引入 default methods 之後,兩者都能提供方法實作。但總體來說,介面更靈活、延伸性更好,也比較不會限制使用者的設計。本章重點就是告訴你:大多數情況下,請選擇介面。
整理 Effective Java 書中 Item 19: Design and document for inheritance or else prohibit it 心得筆記
Java 裡的繼承功能很強,但使用起來也很危險。如果你打算讓別人「繼承你的類別」,你不只是要寫出可以用的 API,還要公開類別的內部行為細節。如果沒做到這一點,繼承後的子類可能會在某次更新中爆掉。
所以這一條的建議是:
如果你沒打算讓別人繼承,就該禁止繼承;
如果你開放繼承,就要設計與文件都做到位。