复用类
类的复用主要有以下的三种方式:组合、继承、代理
一、组合:
将现有类型作为新类型底层实现的一部分来复用。在新类中声明要复用的对象的引用。组合技术通常用于在新类中使用现有类的功能而非它的接口。”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);
}
}