2

这是我实现 Vehicles 接口的抽象类 AbstractVehicles

public abstract class AbstractVehicles implements Vehicles{

}

这是我的 CarImpl

public class CarImpl extends AbstractVehicles implements Car {
    private CarAI ai;
    private static final int CAR_FUEL_LEFT = 10;
    public CarImpl(){
        super(FUEL_LEFT);
        this.ai = new CarAI();
    }        
    public void move(World w){
        // AI is using here
        ai.act(w);
    }
}

这是我的 BicycleImpl

public class BicycleImpl extends AbstractVehicles implements Bicycle {
    private BicycleAI ai;
    private static final int BICYCLE_FUEL_LEFT = 10;
    public BicycleImpl(){
        super(BICYCLE_FUEL_LEFT);
        this.ai = new BicycleAI();
    }        
    public void move(World w){
        // AI is using here
        ai.act(w);
    }
}

其中 Car 和 Bicycle 的接口是标记接口

public interface Car extends Vehicles {
}


public interface Bicycle extends Vehicles {
}

问题来了,我在其他名为 BicycleAI 和 CarAI 的包中分别为汽车和自行车实现了人工智能。但是他们的 CarImpl 和 BicycleImpl 中的代码是相同的。所以我想将它添加到抽象类中,以便可以重用代码。BicycleAI 类和 CarAI 类正在实现接口 AI。

正如我们在上面看到的,它们的行为代码是相同的,但是 AI 对象是不同的。无论如何我可以把这段代码放到抽象类中吗?

我试着这样做

public abstract class AbstractVehicles implements Vehicles{
    protected AI ai;
    private int fuelLeft;
    public AbstractVehicles(int fuelLeft){
        this.fuleLeft = fuelLeft
        AI ai = new AI();
    }
    public void move(World w){
        ai.act(w); // But I have no idea this is CarAI or BicycleAI
    }
}

我对 AbstractVehicles 中的构造函数和 RabbitImpl 中的构造函数有点困惑。如果我创建了一个对象 RabbitImpl,我调用了 move。

4

4 回答 4

2

将 传递AI给抽象类的构造函数。

 public abstract class AbstractVehicles implements Vehicles{
   protected final AI ai;
   public AbstractVehicles(AI ai){
      this.ai = ai;
   }
   public void move(World w){
     ai.act(w);
   }
}

public class CarImpl extends AbstractVehicles implements Car {
   public CarImpl(){
      super(new CarAI());
   } 
}
于 2013-09-16T15:45:26.947 回答
1

除了抽象 AI 之外,您还可以使用模板来使其了解细节

public abstract class AbstractVehicles<AI extends AbstractAI> implements Vehicles {
    protected AI ai;

    public AbstractVehicles(AI ai){
        this.ai = ai;
    }

    public void move(World w){
        ai.move(w);
    }
}

当然,这种设计的缺陷是您不能完全采用泛型类并在抽象类中构造它。但是,您可以对子类执行此操作

public abstract class CarImpl extends AbstractVehicles<CarAI> implements Car{

    public CarImpl(){
        super(new CarAI());
    }
}

通过这样做,CarImpl 中的所有 AI 引用都将通过通用类型识别为 CarAI。

于 2013-09-16T15:48:20.520 回答
1

您可以利用模板方法模式,其中超类通过使用抽象方法将某些步骤推迟到其子类。您在此处委派给子类的步骤是提供您希望子类共享的其余父抽象AI类代码使用的实际实现。

public abstract class AbstractVehicles implements Vehicles{
    protected AI ai;

    public AbstractVehicles(){
        AI ai = initAI();
    }

    protected abstract AI initAI(); // template method

    public void move(World w){
        ai.act(w); // But I have no idea this is CarAI or BicycleAI
    }
}

现在,您的CarBicycle类将提供模板实现为

public class CarImpl extends AbstractVehicles implements Car {

    protected AI initAI() {
        return new CarAI();
    }
}

public class BicycleImpl extends AbstractVehicles implements Car {

    protected AI initAI() {
        return new BicycleAI();
    }
}
于 2013-09-16T15:44:32.373 回答
0

this指的是具体的类。so this.aiorai是对实际实现类字段的引用。

于 2013-09-16T15:44:28.160 回答