【发布时间】:2020-05-12 05:03:50
【问题描述】:
我有一个关于装饰器设计模式的问题。
我有这门课:
class SimpleShip<T extends Weapon> implements Comparable<SpaceShip>{
private T weapon;
private int points = 100;
public SimpleShip(T weapon){
this.weapon = weapon;
}
public int <D extends Weapon> compareTo(SpaceShip<?> other){
return T.quality - D.quality;
}
public void attack(SpaceShip<?> other){
other.gotHit(T.fire());
}
public void gotHit(int reduction){
this.points -= reduction;
}
}
我想创建两种类型的宇宙飞船(两个附加功能) - 两者都是 gotHit 方法的不同实现,我按照以下方式进行:
abstract class ShipDecorator<T extends Weapon> extends SimpleShip<T>{
private SimpleShip<T> simpleShip;
public ShipDecorator(SimpleShip<T> simpleShip){
this.simpleShip = simpleShip;
}
@Override
public void attack(SpaceShip<?> other){
simpleShip.attack();
}
@Override
public int <D extends Weapon> compareTo(SpaceShip<?> other){
return simpleShip.compareTo(other);
}
@Override
public void gotHit(int reduction){
simpleShip.gotHit(reduction);
}
}
class GuardedShip<T extends Weapon> extends ShipDecorator<T>{
public GuardedShip(SimpleShip<T> other, T weapon){
super(other);
}
@Override
private void gotHit(int reduction){
simpleShip.gotHit(reduction);
Random r = new Random();
simpleShip.gotHit(r.nextInt(1,25));
}
}
class SneakyShip<T extends Weapon> extends ShipDecorator<T>{
public SneakyShip(SimpleShip<T> other, T weapon){
super(other);
}
@Override
private void gotHit(int reduction){
if(new Random().nextDouble() > 0.25){
simpleShip.gotHit(reduction);
}
}
}
我的问题是 - SimpleShip API 中的所有方法都应该被装饰器覆盖吗? 我认为他们应该这样做,因为您必须将请求委托给已保存的 SimpleShip 实例,但我为这个问题提供的学校解决方案并没有覆盖它,这让我感到困惑。
【问题讨论】:
-
它覆盖但调用了我猜的上一个方法
-
请记住,您始终可以通过在子类中调用
super来访问扩展类。此外,您的ShipDecorator构造函数不会调用SimpleShip构造函数。请看这里:stackoverflow.com/questions/2056097/… -
我想问的是我的抽象类是否还可以——我是否已经重写了所有的方法(而不仅仅是那些我想要装饰的方法)
-
@PhysicsPrincess 我的建议是将您的代码放入(在线)IDE 并使其运行 - 在您拥有可编译和可执行的代码之后,您可以再次考虑装饰器模式。您似乎遗漏了一些在 Java 中正确执行所需的概念。
-
抱歉,我已经查看了我的评论(第一条评论),但没有意义,因此我将其删除。我目前不同意这两个答案中的任何一个。第一个模仿了我的担忧,我已经撤回了,第二次调用 super 方法对我来说没有意义。我确实同意,如果隐式地调用其他超级方法是没有意义的。