“你好,阿米戈!我想把今天的講座獻給封裝你已經對它有一個大概的了解了。”

封裝 - 1

那麼封裝有什麼好處呢?有很多,但我會指出四個在我看來最重要的:

1) 有效的內部狀態。

程序通常有幾個與同一對象交互的類。通過同時與對象的內部數據交互,它們可能會破壞對象的數據完整性,導致對象停止正常工作。

因此對象必須跟踪對其內部數據的任何更改,或者更好——它應該是進行這些更改的人。

如果我們不希望某個類變量被其他類更改,那麼我們將其聲明為private,這意味著只有該類的方法才能訪問它。如果我們希望變量對其他類是只讀的,那麼我們就給這些變量加上public getter 。

例如,我們可能希望每個人都知道我們的集合中有多少元素,但未經我們的許可,任何人都不能更改它。在這種情況下,我們聲明了一個變量private int count和一個方法public getCount()

適當的封裝保證其他類不能直接訪問我們類的內部數據,因此,在我們無法控制它們的行為的情況下不能改變它。他們必須調用包含將要更改的變量的類的方法。

最好假設其他程序員將始終以對他們最方便的方式使用您的類,而不是以對您(或您的類)最安全的方式。這是錯誤的來源,也是防止錯誤的方法。

2)參數檢查。

有時您需要檢查傳遞給類方法的參數。例如,假設我們有一個代表“人”的類,您可以指定其出生日期。我們應該驗證傳入的任何數據是否符合程序的邏輯和類的邏輯。例如,沒有第 13 個月,沒有 2 月 30 日等。

“為什麼有人會指出 2 月 30 日的出生日期?”

“嗯,首先,這可能是數據輸入錯誤的結果。”

其次,在一個程序像發條一樣運轉之前,它可能有很多錯誤。例如,可能會發生這樣的事情。

程序員編寫代碼來確定誰在後天過生日。假設今天是 3 月 3 日。該程序將當前日期加 2 並找到所有出生於 3 月 5 日的人。到目前為止一切順利。

但是當 3 月 30 日到來時,程序找不到任何人,因為沒有 3 月 32 日。當方法執行參數檢查時,程序的錯誤要少得多。”

“我記得我們研究 ArrayList 的時候我看它的代碼,在 get 和 set 方法中有檢查以確保索引參數大於或等於零且小於數組的長度。代碼會拋出一個如果數組沒有與索引對應的元素,則異常。

“是的,那是經典的輸入檢查。

3) 在類內更改代碼時錯誤更少。

假設我們編寫了一個非常有用的類作為一個大型項目的一部分。每個人都非常喜歡它,以至於其他程序員開始在他們自己的代碼中的數百個地方使用它。

該課程被證明非常有用,因此您決定對其進行改進。但是如果你去掉類中的任何一個方法,許多其他程序員的代碼將無法再編譯。他們將不得不快速重寫代碼。而且發生的重寫越多,出現錯誤的機會就越多。如果你經常破壞構建,你會被討厭。

但是,如果我們更改標記為私有的方法,我們就會知道這些方法不會在任何地方被其他任何人的代碼調用。我們可以重寫它們,改變參數的數量和類型,依賴的代碼仍然可以工作。或者至少它仍然會編譯。

4) 我們定義其他對象將如何與我們的對象交互。

我們可以限制可以對我們的對象執行的操作。例如,我們可能只想創建一個類的一個實例——即使它是在項目中的多個地方同時創建的。我們可以使用封裝來實現這一點。

封裝 - 2

封裝讓我們可以施加額外的限制,這些限制可能會轉化為額外的好處。例如,String 類被實現為不可變對象。String 類的實例在創建和銷毀之間不能更改。String 類的所有方法(remove、substring,...)都返回一個新字符串,並且絕不會更改調用它們的對象。

“天哪。就是這樣。”

“封裝很有趣。”

“我同意。”