面向物件——三大基本特徵
面向物件的三大基本特徵:封裝、繼承和多型
一、封裝
利用抽象資料型別將資料和基於資料的操作封裝在一起,使其構成一個不可分割的獨立實體。資料被保護在抽象資料型別的內部,儘可能地隱藏內部的細節,只保留一些對外介面使之與外部發生聯絡。使用者無需知道物件內部的細節,但可以通過物件對外提供的介面來訪問該物件。
優點:
減少耦合:可以獨立地開發、測試、優化、使用、理解和修改
減輕維護的負擔:可以更容易被程式設計師理解,並且在除錯的時候可以不影響其他模組
有效地調節效能
提高軟體的可重用性
降低了構建大型系統的風險:即使整個系統不可用,但是這些獨立的模組卻有可能是可用的
以下 Person 類封裝 name、gender、age 等屬性,外界只能通過 get() 方法獲取一個 Person 物件的 name 屬性和 gender 屬性,而無法獲取 age 屬性,但是 age 屬性可以供 work() 方法使用。
注意到 gender 屬性使用 int 資料型別進行儲存,封裝使得使用者注意不到這種實現細節。並且在需要修改 gender 屬性使用的資料型別時,也可以在不影響客戶端程式碼的情況下進行(因為這裡沒有使用set()方法
public class Person { private String name; private int gender; private int age; public String getName() { return name; } public String getGender() { return gender == 0 ? "man" : "woman"; } public void work() { if (18 <= age && age <= 50) { System.out.println(name + " is working very hard!"); } else { System.out.println(name + " can't work any more!"); } } }
二、繼承
繼承實現了 IS-A 關係,例如 Cat 和 Animal 就是一種 IS-A 關係,因此 Cat 可以繼承自 Animal,從而獲得 Animal 非 private 的屬性和方法。
Cat 可以當做 Animal 來使用,也就是說可以使用 Animal 引用 Cat 物件。父類引用指向子類物件稱為 向上轉型 。
- 子類獲得父類 非 private 的屬性和方法。
- 向上轉型 Animal animal = new Cat();
- 繼承應該遵循里氏替換原則,子類物件必須能夠替換掉所有父類物件。
三、多型
多型分為編譯時多型和執行時多型。編譯時多型主要指方法的過載,執行時多型指程式中定義的物件引用所指向的具體型別在執行期間才確定。
執行時多型有三個條件:繼承 , 覆蓋(重寫), 向上轉型
下面的程式碼中,樂器類(Instrument)有兩個子類:Wind 和 Percussion,它們都覆蓋了父類的 play() 方法,並且在 main() 方法中使用父類 Instrument 來引用 Wind 和 Percussion 物件。在 Instrument 引用呼叫 play() 方法時,會執行實際引用物件所在類的 play() 方法,而不是 Instrument 類的方法。
public class Instrument {
public void play() {
System.out.println("Instument is playing...");
}
}
public class Wind extends Instrument {
public void play() {
System.out.println("Wind is playing...");
}
}
public class Percussion extends Instrument {
public void play() {
System.out.println("Percussion is playing...");
}
}
public class Music {
public static void main(String[] args) {
List<Instrument> instruments = new ArrayList<>();
instruments.add(new Wind());
instruments.add(new Percussion());
for(Instrument instrument : instruments) {
instrument.play();
}
}
}