Java 中组合和接口的实际使用?

rre*_*ene 2 java interface composition

我很难理解如何一起使用组合和接口来支持组合而不是继承?一个例子可以是:

界面:

public interface IMachine {
    void TurnOn();
    void TurnOff();
}
Run Code Online (Sandbox Code Playgroud)

Machine 类是 Printer 类的父类

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;
    }

}
Run Code Online (Sandbox Code Playgroud)

现在,如果我创建一个实现 IMachine 接口的打印机类,它将实现 IMachine 接口的方法。但是假设我创建了一个实现 IMachine 接口的 Clock 类,那么我必须再次实现这些方法。是否有更有效的方法来使用组合和接口并将方法委托给 Machine 类?

And*_*eas 6

通过继承,您将拥有一个具有共享逻辑的基类,以及使用该共享逻辑的子类。该基类的任何公共方法都是共享 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
}
Run Code Online (Sandbox Code Playgroud)

作品

public interface Machine {
    void turnOn();
    void turnOff();
}
final class MachineImpl {
    public void turnOn() {/*logic here*/}
    public 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
}
Run Code Online (Sandbox Code Playgroud)

的用户Machine仍将看到相同的公共 API, 的用户Heater仍将看到相同的公共 API,但逻辑已重新定位。

这允许Heater实现多个独立的“功能”,这是使用继承时不可能实现的。