在 Java 中一起实际使用组合和界面?
Practical use of composition and interface together in Java?
我很难理解如何结合使用组合和接口来支持组合而不是继承?例如:
接口:
public interface IMachine {
void TurnOn();
void TurnOff();
}
机器 Class 是打印机 Class 的父 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 接口的打印机 Class,它将实现 IMachine 接口的方法。但是假设我创建了一个实现 IMachine 接口的 Clock Class,然后我必须以更有效的方式实现这些方法 again.Is 我们使用组合和接口并将方法委托给 Machine class?
通过继承,您将拥有一个具有共享逻辑的基 class,以及使用该共享逻辑的子class。该基础 class 的任何 public 方法都是共享的 API。
通过组合,接口定义了共享 API,每个实现 class(之前是子classes 的)将把这些调用委托给组合 class 实际上具有共享逻辑。
继承
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 {
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
}
Machine
的用户仍会看到相同的 public API,Heater
的用户仍会看到相同的 public API,但逻辑已被重新定位。
这允许 Heater
实现多个独立的“功能”,这在使用继承时是不可能的。
组合通常在 "has a" 关系中引用。在这种情况下,例如,如果您有 PowerSwitch 对象的概念,则可以使用组合。这将在 Machine "has a" PowerSwitch.
的通知中实现
继承通常被称为 "is a" 关系,如打印机 "is a" 机器的情况。
使用 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();
}
}
或类似的东西。然后打印机和时钟都可以扩展 AbstractMachine。
编辑:Re-reading 我看到的问题是您想要合成而不是继承(我正在阅读它,因为您想要同时使用两者)。在那种情况下,只需直接在 Printer/Clock 类.
中使用电源开关即可
我很难理解如何结合使用组合和接口来支持组合而不是继承?例如:
接口:
public interface IMachine {
void TurnOn();
void TurnOff();
}
机器 Class 是打印机 Class 的父 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 接口的打印机 Class,它将实现 IMachine 接口的方法。但是假设我创建了一个实现 IMachine 接口的 Clock Class,然后我必须以更有效的方式实现这些方法 again.Is 我们使用组合和接口并将方法委托给 Machine class?
通过继承,您将拥有一个具有共享逻辑的基 class,以及使用该共享逻辑的子class。该基础 class 的任何 public 方法都是共享的 API。
通过组合,接口定义了共享 API,每个实现 class(之前是子classes 的)将把这些调用委托给组合 class 实际上具有共享逻辑。
继承
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 {
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
}
Machine
的用户仍会看到相同的 public API,Heater
的用户仍会看到相同的 public API,但逻辑已被重新定位。
这允许 Heater
实现多个独立的“功能”,这在使用继承时是不可能的。
组合通常在 "has a" 关系中引用。在这种情况下,例如,如果您有 PowerSwitch 对象的概念,则可以使用组合。这将在 Machine "has a" PowerSwitch.
的通知中实现继承通常被称为 "is a" 关系,如打印机 "is a" 机器的情况。
使用 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();
}
}
或类似的东西。然后打印机和时钟都可以扩展 AbstractMachine。
编辑:Re-reading 我看到的问题是您想要合成而不是继承(我正在阅读它,因为您想要同时使用两者)。在那种情况下,只需直接在 Printer/Clock 类.
中使用电源开关即可