合成與繼承都能將子物件置入新類別,但選擇標準在於:是否需要暴露既有類別的介面。
private 物件,僅透過自定義介面使用其功能。
//: Car.java
// Composition with public objects
class Engine { public void start() {} public void rev() {} public void stop() {} }
class Wheel { public void inflate(int psi) {} }
class Window { public void rollup() {} public void rolldown() {} }
class Door { public Window window = new Window(); public void open() {} public void close() {} }
public class Car {
public Engine engine = new Engine();
public Wheel[] wheel = new Wheel[4];
public Door left = new Door(), right = new Door();
Car() { for(int i=0;i<4;i++) wheel[i]=new Wheel(); }
public static void main(String[] args) {
Car car = new Car();
car.left.window.rollup();
car.wheel[0].inflate(72);
}
} ///:~
汽車「包含」引擎、車輪、車門,故障分析時需考慮組裝細節,將成員設為 public 讓用戶端直接操作合成物件,介面更直觀,也降低類別創建者的複雜度。
汽車不「包含」車輛,而是「屬於」車輛的一種。這種「is-a」關係必須用繼承表達。程式應專注於建立與操作型別物件,以模型化問題空間。