你好!今天的講座將專門討論封裝,我們將立即通過示例開始:)在您面前的是一台熟悉的汽水機。我有一個問題想問你:它是如何運作的?試著詳細回答:玻璃杯來自哪裡,內部溫度如何保持,冰塊存放在哪裡,機器如何理解要添加什麼糖漿等。最有可能的是,您沒有這些問題的答案。好吧,也許不是每個人都使用這樣的機器;它們現在不那麼流行了。讓我們試著舉另一個例子。你知道你每天都會使用很多次的東西。哦,我有一個主意! 告訴我們Google 搜尋引擎是如何運作的。它到底是如何根據您輸入的單字搜尋資訊的?為什麼這些結果位於頂部而不是其他結果?儘管您每天都使用 Google,但您可能不知道。但這並不重要。畢竟,你不需要知道這一點。 您可以在搜尋引擎中輸入查詢,而無需考慮它到底是如何運作的。您可以從自動販賣機購買蘇打水,而不知道它是如何運作的。即使在學校水平,你也可以在不深入研究內燃機操作、甚至不了解物理的情況下駕駛汽車。這一切之所以成為可能,要歸功於物件導向程式設計的主要原則之一——封裝。在閱讀有關該主題的各種文章時,您可能會發現程式設計中有兩個常見概念 -封裝和隱藏。作者所說的「封裝」這個字有這樣或那樣的意思(正如它所發生的)。我們將分解這兩個術語,以便您有一個完整的理解。程式設計中「封裝」一詞的原始意義是將資料和使用該資料的方法組合在一個套件(「膠囊」)中。在Java中,類別充當膠囊包。類別包含資料(類別欄位)和處理該資料的 方法。 這對您來說似乎是顯而易見的,但在其他程式設計概念中,一切的工作方式都不同。例如,在函數式程式設計中,資料與其操作嚴格分離。在 OOP(物件導向程式設計)中,程式由膠囊類別組成,膠囊類別既是資料也是使用它的函數。現在我們來談談隱藏。我們如何使用各種複雜的機製而不了解它們如何運作以及它們的工作是基於什麼?很簡單:它們的創建者提供了一個簡單且用戶友好的介面。在汽水機上,介面是面板上的按鈕。只需按一個按鈕,即可選擇玻璃杯的體積。按第二個按鈕即可選擇糖漿。第三個負責加冰。這就是您所要做的。機器內部設計得如何精確並不重要。最重要的是,它的設計方式是使用者需要按三個按鈕才能獲得蘇打水。汽車也是如此。他內心發生什麼事並不重要。最主要的是,當你踩右踏板時,汽車前進,當你踩左踏板時,汽車減速。這正是隱藏的本質。程式的所有「內部」對使用者都是隱藏的。對他來說,這些資訊是多餘的,也是不必要的。使用者需要的是最終結果,而不是內部過程。讓我們以該類為例
Auto
:
public class Auto {
public void gas() {
/*some complicated things are happening inside the car
as a result of which it goes forward*/
}
public void brake() {
/*some complicated things are happening inside the car
as a result of which it slows down*/
}
public static void main(String[] args) {
Auto auto = new Auto();
// How everything looks to the user
//pressed one pedal - went
auto.gas();
//pressed another pedal - braked
auto.brake();
}
}
這就是 Java 程式中的實作隱藏的樣子。一切都像現實生活中一樣:為使用者提供一個介面(方法)。如果他需要程式中的汽車執行某個動作,他只需要呼叫所需的方法。這些方法內部發生的都是不必要的訊息,最主要的是一切都按其應有的方式進行。這裡我們談到隱藏實現。除此之外,Java還有資料隱藏功能。我們在有關 getter 和 setter 的講座中寫到了這一點,但提醒您也沒什麼壞處。例如,我們有一個類別Cat
:
public class Cat {
public String name;
public int age;
public int weight;
public Cat(String name, int age, int weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
public Cat() {
}
public void sayMeow() {
System.out.println("Meow!");
}
}
也許你還記得上一堂課的問題是什麼?如果沒有,讓我們記住。問題是他的數據(字段)對所有人開放,另一個程式設計師可以輕鬆地在程式中創建一隻體重為0、年齡為-1000歲的無名貓:
public static void main(String[] args) {
Cat cat = new Cat();
cat.name = "";
cat.age = -1000;
cat.weight = 0;
}
在這種情況下,您可以密切監視您的一位同事是否正在建立具有錯誤狀態的對象,但最好排除建立此類「錯誤對象」的可能性。 它們幫助我們隱藏數據:
- 存取修飾符(private、protected、package default);
- getter 和 setter。
- 監視對象的正確狀態。上面有這樣的例子:借助 setter 和 private 修飾符,我們保護了我們的程序免受權重為 0 的貓的侵害。
- 介面的使用者友善性。我們僅將方法保留在「外部」以供使用者存取。他只要打電話給他們就可以得到結果,根本不需要深究他們的工作細節。
- 程式碼的更改不會影響使用者。我們在方法內部進行所有更改。這不會影響使用者:他為汽車的汽油寫了auto.gas(),所以他會寫它。事實上,我們在 Gas() 方法的操作中更改了某些內容,他仍然看不到:他和以前一樣,只會收到所需的結果。
GO TO FULL VERSION