我可以将对象从子类传递给抽象类吗?

时间:2013-09-16 15:33:56

标签: java oop design-patterns

这是我的抽象类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 {
}

问题来了 我已经在其他包装中单独实现了汽车和自行车的AI 叫做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,我会调用此移动。

4 个答案:

答案 0 :(得分: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());
   } 
}

答案 1 :(得分:1)

您可以使用模板方法模式,其中Super类通过使用 abstract 方法将某些步骤推迟到其Sub类。您在此处委派给子类的步骤是提供实际的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();
    }
}

答案 2 :(得分: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。

答案 3 :(得分:0)

this指的是具体的类。因此this.aiai是对实际实现类字段的引用。