菜雞與物件導向 (3): 封裝
封裝包含了兩個重要的觀念:
- 控制物件和外部進行互動的出入口
- 隱藏物件內部的細節資訊
強者我同事整理的文章裡的例子就舉得不錯:當你按下鍵盤的A鍵,螢幕隨即出現了A,你不必知道中間發生了什麼事,你只需要知道怎麼操作和最後得到什麼就可以了。
其中鍵盤提供的按鍵,就是我們對電腦進行互動的出入口;而電腦實際上做了什麼事情,也被隱藏了起來,讓我們只需要關注結果就好。
此外我也看到過販賣機的例子,當你去販賣機買飲料,你也不需要知道裡面的構造,只要知道你選了飲料投了錢,飲料就會跑出來就行。
從上面的兩個例子,相信大家已經掌握到封裝的概念了:將物件視作一個整體,把內部的實作內容隱藏起來,讓使用者只需要知道怎麼使用這個物件即可。(相似的思路,我們後續的介面會再提到)
如果封裝做得夠好,除了可以將程式碼整理得井井有條以外,也能讓物件內部的修改不會直接影響到使用物件的地方,達成了降耦合的目標
並且也能讓物件的使用者直覺地知道如何使用物件提供的方法,如此使用者就可以專注在更高層次的抽象,而不用被物件內部的細節所干擾。
最後,從上面的敘述中我們可以察覺到要實現封裝,最重要的就是:對外的開放程度(存取範圍)的控制。或是套一句前輩的說法:給程式碼隱私的空間。
補充:如果想問「什麼是耦合?」的朋友,建議可以看看這篇:實務上的高內聚與低耦合
或是參照本系列後續的 內聚與耦合
存取範圍與存取子
先讓我們從存取範圍開始說起吧,因為我個人慣用的是 C#,因此就介紹一下 C# 是怎麼控制存取範圍的。
在 C# 之中,類別裡控制可見度是使用修飾子來定義存取範圍,也就是當我們替類別宣告欄位時常看到的 Public
和 Private
。
Public
: 這是公開的,所有人都看得到Private
: 這是私有的,只有自己看得到
除了最常用的這兩個以外,還有其他的修飾子可以先知道一下:
Protected
: 這是受到保護的,只有自己和繼承的孩子們看得到internal
: 這是內部的,只有身為同一個組件的朋友們看得到Protected internal
:組合上面兩個,也就是可以給同個組件的朋友們,或是其他組件繼承的孩子們看見
接下來的部分會以最常見的 Public
和 Private
來繼續說明,對存取範圍的這些修飾子有興趣的朋友,可以參照 存取範圍層級 的說明。
現在我們已經知道了有哪些修飾子可以用來控制存取範圍,但為什麼我們會需要宣告存取範圍的大小呢?其根本是為了將控制權掌握在物件本身。
就像大話設計模式比喻的:物件就像間房子,我們不希望被看光光,可以看見的 Public
就像門和窗,而不該看見的 Private
則是用牆壁隱藏起來,而對於這間房子而言,門窗是可以控制的。