[原創文章歡迎轉載,但請保留作者信息]
Justin 于 2009-12-20
大師寫到這一章節的時候文風似有明顯轉變,原因未知,但我更喜歡這章的風格。如題,Item22的主旨是應該把所有類的數據成員聲明為私有(private)。因為:
-
如果數據成員都是私有的,那么訪問這些成員就只能通過函數進行。于是用戶就不需要費心考慮到底要用什么方式去訪問數據成員:因為只有定義了的函數可以用。
-
通過定義數據成員為私有,可以實現函數來設計、約束或禁止對這些成員的各種訪問(讀/寫等)。而如果將其設為公有(public),你將無法得知你的成員會被誰改動,也不知道會是怎樣的改動。
-
而更重要的好處是封裝(encapsulation):可以方便的通過修改函數來改變成員的訪問方式;在成員被訪問時通知其他對象;實現多線程中的同步等等。
封裝的好處究其本質,是通過對用戶隱藏數據成員來保證類行為的一致性(class invariant)。因為接口被成員訪問函數限制了,類的作者也為自己日后修改類的實現留了后路:如果所有的成員都是公有的,對任何代碼的修改都有可能影響到外界的使用。(因此Scott說“Public means unencapsulated, and practically speaking, unencapsulated means unchangeable, especially for classes that are widely used.”)
那么可不可以聲明為保護(protected)呢?其實道理和前面的公有是一樣的。公有的成員對類的外部完全開放,而保護的成員對類的繼承者完全開放。這個就像兩個區間:(-infinity, +infinity) 和 (0, +infinity),兩者的大小是一樣的。
接下來大師的一句話有擊中要害:從分裝的角度,只有兩種訪問級別:私有,及其他。