我很难理解如何使用合成和界面来支持合成而不是继承?一个例子可能是:
接口:
public interface IMachine {
void TurnOn();
void TurnOff();
}
Machine Class是打印机类的父类
public class Machine {
protected boolean isOn;
public Machine(boolean isOn) {
this.isOn = isOn;
}
public void TurnOn() {
isOn = true;
System.out.println("Machine is on !");
}
public void TurnOff() {
isOn = false;
}
}
现在,如果我创建一个实现IMachine接口的Printer Class,它将实现IMachine接口的方法。但是,假设我创建了一个实现IMachine接口的Clock Class,那么我必须再次实现这些方法。有一种更有效的方法,我们使用组合和接口并将方法委托给Machine类吗?
答案 0 :(得分:2)
通过继承,您将拥有一个具有共享逻辑的基类,以及使用该共享逻辑的子类。该基类的任何公共方法都是共享API。
使用组合,接口定义共享API,每个实现类(之前是子类)都将这些调用委托给实际具有共享逻辑的复合类。
继承
public abstract class Machine {
public void turnOn() {/*logic here*/}
public void turnOff() {/*logic here*/}
}
public final class Heater extends Machine {
// heater methods here
}
组合物
public interface Machine {
public void turnOn();
public void turnOff();
}
final class MachineImpl {
void turnOn() {/*logic here*/}
void turnOff() {/*logic here*/}
}
public final class Heater implements Machine {
private MachineImpl impl = new MachineImpl();
@Override public void turnOn() { this.impl.turnOn(); }
@Override public void turnOff() { this.impl.turnOff(); }
// heater methods here
}
Machine
的用户仍会看到相同的公共API,Heater
的用户仍会看到相同的公共API,但逻辑已重新定位。
这允许Heater
实现多个独立的"功能",这是使用继承时无法实现的。
答案 1 :(得分:0)
组成通常以“有”关系表示。在这种情况下,如果您具有PowerSwitch对象的概念,则可以使用组合。这可以在机器“具有”PowerSwitch的通知中实现。
继承通常被称为“是一种”关系,就像你的打印机“是机器”一样。
使用PowerSwitch对象,您可以包含打印机和时钟的功能,可能在AbstractMachine中
public abstract class AbstractMachine implements IMachine {
private PowerSwitch machinePowerSwitch;
public void turnOff() {
machinePowerSwitch.turnOff();
}
public void turnOn() {
machinePowerSwitch.turnOn();
}
public void isOn() {
return machinePowerSwitch.getPowerState();
}
}
或类似的东西。然后,Printer和Clock都可以扩展AbstractMachine。
编辑:重新阅读我看到你想要的组合INSTEAD OF继承的问题(我正在阅读它,因为你想要同时使用它们)。在这种情况下,只需直接在打印机/时钟类中使用powerswitch。