装饰设计模式(Java)中的重写方法
我有一个关于装饰设计模式的问题 我有这门课:装饰设计模式(Java)中的重写方法,java,oop,decorator,Java,Oop,Decorator,我有一个关于装饰设计模式的问题 我有这门课: 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 e
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;
}
}
类SimpleShip实现了可比较的{
私人T型武器;
私人积分=100;
公共简易程序(T武器){
这个武器=武器;
}
公共国际比较(宇宙飞船其他){
返回T.quality-D.quality;
}
公共空间攻击(宇宙飞船其他){
其他。gotHit(T.fire());
}
公共无效的gotHit(整数减少){
这个点-=减少;
}
}
我想创建两种类型的宇宙飞船(两种新增功能)-都是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);
}
}
}
抽象类ShipDecorator扩展了SimpleShip{
私人单纯形;
公共船舶装饰师(SimpleShip SimpleShip){
this.simpleShip=simpleShip;
}
@凌驾
公共空间攻击(宇宙飞船其他){
simpleShip.attack();
}
@凌驾
公共国际比较(宇宙飞船其他){
返回simpleShip.compareTo(其他);
}
@凌驾
公共无效的gotHit(整数减少){
simpleShip.gotHit(还原);
}
}
类GuardShip扩展ShipDecorator{
公卫舰(简易舰、其他T型武器){
超级(其他);
}
@凌驾
私密空位命中(智力降低){
simpleShip.gotHit(还原);
随机r=新随机();
高希特(r.nextInt(1,25));
}
}
类SkillyShip扩展了ShipDecorator{
公众偷偷摸摸(单纯形,其他,T型武器){
超级(其他);
}
@凌驾
私密空位命中(智力降低){
如果(新随机().nextDouble()>0.25){
simpleShip.gotHit(还原);
}
}
}
我的问题是-SimpleShip的API中的所有方法都应该被装饰器覆盖吗?
我认为他们应该这样做,因为您必须将请求委托给保存的SimpleShip实例,但我针对这个问题提供的学校解决方案没有覆盖它,这让我感到困惑。装饰器模式应该在您突出显示时向船舶添加其他功能,因为核心功能已经存在于基本船舶中。这个
SimpleShip
总是附带这些功能
你对装饰图案的看法基本上是正确的,但当你装饰这艘船时,你必须保留核心特征和附加特征。这意味着gotHit
应该做SimpleShip
所做的+其他guardeship
所做的事情
那么,这在代码方面意味着什么
在执行其他操作之前,应先调用原始的gotHit()
:
class SneakyShip<T extends Weapon> extends ShipDecorator<T>{
public SneakyShip(SimpleShip<T> other, T weapon){
super(other);
}
@Override
private void gotHit(int reduction){
super.gotHit(reduction); // core behaviour of every ship
// additional feature of guarded ships
if(new Random().nextDouble() > 0.25){
// more damage
}
}
}
class SkileyShip扩展了ShipDecorator{
公众偷偷摸摸(单纯形,其他,T型武器){
超级(其他);
}
@凌驾
私密空位命中(智力降低){
super.gotHit(reduction);//每艘船的核心性能
//受保护船舶的附加功能
如果(新随机().nextDouble()>0.25){
//更多损害
}
}
}
您在代码中所做的是完全改变有关gotHit
行为的船舶行为
这里有一些我不会说它必须重写
SimpleShip
的方法,如果它实际上没有在重写的方法中做任何事情,并且它将等于
@Override
public void method() {
super.method();
}
然后您将生成更多的代码行。如果你想装饰任何东西,那么你显然需要覆盖
要重用您的示例,尽管有点奇怪:
class SneakyShip<T extends Weapon> extends ShipDecorator<T>{
public SneakyShip(SimpleShip<T> other, T weapon){
super(other);
}
// This is fine, it adds functionality.
@Override
private void gotHit(int reduction){
super.gotHit(reduction); // You forgot to call the methods of the superclasses.
if(new Random().nextDouble() > 0.25){
simpleShip.gotHit(reduction);
}
}
// This is unnecessary, because it is implicitly done.
@Override
public void attack(SpaceShip<?> other){
super.attack(other);
}
}
class SkileyShip扩展了ShipDecorator{
公众偷偷摸摸(单纯形,其他,T型武器){
超级(其他);
}
//这很好,它增加了功能。
@凌驾
私密空位命中(智力降低){
super.gotHit(reduce);//您忘记调用超类的方法了。
如果(新随机().nextDouble()>0.25){
simpleShip.gotHit(还原);
}
}
//这是不必要的,因为它是隐式完成的。
@凌驾
公共空间攻击(宇宙飞船其他){
超级攻击(其他);
}
}
如果给您提供了一种编程语言,该语言在没有显式告诉被重写方法的情况下不会自动调用被重写的方法,则需要这样做
有关更多信息,请参阅四人帮的设计模式手册。它覆盖但调用了前面的方法。我想你记得,你总是可以通过调用子类中的
super
来访问扩展类。此外,您的ShipDecorator
构造函数不会调用SimpleShip
构造函数。请看这里:我想问的是我的抽象类是否可以-我在那里重写了所有的方法(而不仅仅是那些我想要修饰的方法)可以吗@PhysicsPrincess我的建议是将您的代码放到一个IDE并使其运行—在您拥有可编译和可执行的代码之后,您可以再次考虑Decorator模式。您似乎缺少一些在Java中正确使用的概念。对不起,我已经查看了我的注释(第一条注释),但没有任何意义,因此我将其删除。目前我不同意这两个答案中的任何一个。第一个模拟了我的顾虑,我已经撤回了,第二个调用super方法对我来说没有意义。我确实同意,如果是隐式调用,那么只显式调用其他超级方法是没有意义的。但是我认为super.method()不会有帮助。。您需要使用simpleShip.method()。。要将请求委托给修饰对象,还是我错了?您需要在执行任何实际修饰之前调用超类的方法,因此super.method()
,因为否则您将忽略以前所有方法调用的结果。但是如果您不添加任何功能,那么您就没有