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 のインターフェースは、marker Interface です。

public interface Car extends Vehicles {
}


public interface Bicycle extends Vehicles {
}

ここで質問です。私は、自動車と自転車の AI を、BicycleAI と CarAI という他のパッケージに個別に実装しました。しかし、CarImpl と BicycleImpl のコードは同じです。したがって、コードを再利用できるように、それを抽象クラスに追加したいと思います。そしてクラス BicycleAI とクラス CarAI はインターフェイス AI を実装しています。

上記のように、act のコードは同じですが、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 に答える
0

これは具体的なクラスを指します。So this.aioraiは実際の実装クラス フィールドへの参照です。

于 2013-09-16T15:44:28.160 に答える