复用类
类的复用主要有以下的三种方式:组合、继承、代理
一、组合:
将现有类型作为新类型底层实现的一部分来复用。在新类中声明要复用的对象的引用。组合技术通常用于在新类中使用现有类的功能而非它的接口。”has-a”的关系
二、继承:
组合和继承都是在新的类中放置子对象,组合是显式的这样做,继承则是隐式的这样做。继承是使用现有类,为了某种特殊需要将其特殊化。“is-a”的关系.
三、代理:
继承和组合的中庸之道。将一个成员对象置于要构造的类中(就像组合),与此同时在新类中暴露了该类成员所有的方法(就像继承)。举例如下:
太空飞船控制模块
public class SpaceShipControls { void up(int velocity) {} void down(int velocity) {} void left(int velocity) {} void right(int velocity) {} void forward(int velocity) {} void back(int velocity) {} void turboBoost() {} }
如果使用继承,假如SpaceShip继承控制模块(如下),但是SpaceShip并不是真正的SpaceShipControls的类型,显得不伦不类。即便它可以forward.
public class SpaceShip extends SpaceShipControls { private String name; public SpaceShip(String name) { this.name = name; } public String toString() { return name; } public static void main(String[] args) { SpaceShip protector = new SpaceShip("NSEA Protector"); protector.forward(100); } }
太空船代理
public class SpaceShipDelegation { private String name; private SpaceShipControls controls = new SpaceShipControls(); public SpaceShipDelegation(String name) { this.name = name; } // Delegated methods: public void back(int velocity) { controls.back(velocity); } public void down(int velocity) { controls.down(velocity); } public void forward(int velocity) { controls.forward(velocity); } public void left(int velocity) { controls.left(velocity); } public void right(int velocity) { controls.right(velocity); } public void turboBoost() { controls.turboBoost(); } public void up(int velocity) { controls.up(velocity); } public static void main(String[] args) { SpaceShipDelegation protector = new SpaceShipDelegation("NSEA Protector"); protector.forward(100); } }
四、结合使用组合和代理
class Plate { Plate(int i) { System.out.println("Plateconstructor"); } } class DinnerPlate extends Plate { DinnerPlate(int i) { super(i); System.out.println("DinnerPlateconstructor"); } } // 器具 class Utensil { Utensil(int i) { System.out.println("Utensilconstructor"); } } // 汤匙 class Spoon extends Utensil { Spoon(int i) { super(i); System.out.println("Spoonconstructor"); } } class Fork extends Utensil { Fork(int i) { super(i); System.out.println("Forkconstructor"); } } class Knife extends Utensil { Knife(int i) { super(i); System.out.println("Knifeconstructor"); } } // A cultural way of doingsomething: class Custom { Custom(int i) { System.out.println("Customconstructor"); } } publicclass PlaceSetting extends Custom { private Spoon sp; private Fork frk; private Knife kn; private DinnerPlate pl; public PlaceSetting(int i) { super(i + 1); sp = new Spoon(i + 2); frk = new Fork(i + 3); kn = new Knife(i + 4); pl = new DinnerPlate(i + 5); System.out.println("PlaceSettingconstructor"); } public static void main(String[] args) { PlaceSetting x = new PlaceSetting(9); } } /* * Output: Customconstructor Utensil constructor Spoon constructor Utensil * constructor Forkconstructor Utensil constructor Knife constructor Plate * constructor DinnerPlateconstructor PlaceSetting constructor */
五、在组合和继承之间选择
“is-a”的关系用继承,“has-a”的关系用组合。
class Vehicle { } 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 extends Vehicle { public Engine engine = new Engine(); public Wheel[] wheel = new Wheel[4]; public Doorleft = new Door(), right = new Door(); // 2-door public 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); } }