解决此Java继承难题的最佳方法是什么?

时间:2019-01-18 01:52:03

标签: java inheritance

首先是汽车课:

public class Car {

    private final Engine engine;

    public Car(int x, int y) {

      this.engine = createEngine(x, y);

      // (...)
    }

    protected Engine createEngine(int x, int y) {
         return new Engine(x ,y);
    }
}

现在我想创建一个FastCar,它将需要一个FastEngine,而不仅仅是引擎。

public class FastEngine extends Engine {

    public FastEngine(int x, int y, double a, double b) {
        super(x, y);
        // (...)
    }

    // (...)
}

public class FastCar extends Car {

    private final double a;
    private final double b;

    public FastCar(int x, int y, double a, double b) {
        super(x, y);
        this.a = a;
        this.b = b;
    }

    @Override
    protected Engine createEngine(int x, int y) {
        // of course I can't use a and b here, they were not initialized yet :( :( :(
        return new FastEngine(x, y /* I need a and b here too :( */);
    }
}

所以问题是在我的新FastCar类上,我需要将Engine切换为FastEngine,但是FastEngine现在接受在构造函数中传递的参数a和b。看来我已经走到了尽头,除了用新的实体模型从头重写所有内容之外,我还能做什么?

3 个答案:

答案 0 :(得分:2)

我建议创建一个引擎工厂。请记住“ Single Responsibility”原理(SOLID)。

在现实生活中,您不会在汽车内安装引擎。您单独进行。有时在另一家工厂。发动机正在装配线上安装在汽车上。

这为您提供了更大的灵活性-在工厂和代码上。

进一步,我建议实施builder pattern-如果您要在汽车中安装更多零件。

P.s。忽略“静态”-我只是添加了它们以避免IDE警告。

public static void main(String[] args) {
    Car car = new Car(EngineFactory.createEngine(1, 2));
    Car fastCar = new FastCar(EngineFactory.createEngine(1, 2, 1d, 2d), 1d, 2d);
}

static class EngineFactory{
    public static Engine createEngine(int x, int y){
        return new Engine(x, y);
    }

    public static Engine createEngine(int x, int y, double a, double b){
        return new FastEngine(x, y, a, b);
    }
}

public static class Car {
    private final Engine engine;
    public Car(Engine engine) {
        this.engine = engine;
    }
}

public static class FastCar extends Car {

    private final double a;
    private final double b;

    public FastCar(Engine engine, double a, double b) {
        super(engine);
        this.a = a;
        this.b = b;
    }
}

public static class FastEngine extends Engine {
    public FastEngine(int x, int y, double a, double b) {
        super(x, y);
    }
}

public static class Engine{
    int x;
    int y;

    public Engine(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

答案 1 :(得分:1)

尽管我确实同意问题的措辞不够明确的意见,但我会为您提供解决方案。随时添加泛型使其更漂亮。

public class Car {

    static class CarConfig {
        int x;
        int y;

        CarConfig(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    private final Engine engine;

    public Car(int x, int y) {

      this(new CarConfig(x, y));
    }

    Car(CarConfig config) {
         this.engine = createEngine(config);
    }

    protected Engine createEngine(CarConfig config) {
         return new Engine(config.x ,config.y);
    }
}

然后在您的子类中:

public class FastEngine extends Engine {

    public FastEngine(int x, int y, double a, double b) {
        super(x, y);
        // (...)
    }

    // (...)
}

public class FastCar extends Car {

    static class FastCarConfig extends CarConfig {
         double a;
         double b;

         FastCarConfig(int x, int y, double a, double b) {
             super(x, y);
             this.a = a;
             this.b = b;
         }
     }


    private final double a;
    private final double b;

    public FastCar(int x, int y, double a, double b) {
        super(new FastCarConfig(x, y, a, b);
        this.a = a;
        this.b = b;
    }

    @Override
    protected Engine createEngine(CarConfig config) {
        if (config instanceof FastCarConfig) throw new IllegalStateException("You messed up!");
        FastCarConfig c = (FastCarConfig) config;
        return new FastEngine(c.x, c.y, c.a, c.b);
    }
}

B O O M!

答案 2 :(得分:1)

将引擎构造移回汽车制造商。如果创建引擎需要的不仅仅是构造函数调用,则将其移至静态构造函数。

class Engine {
    private final int x;
    private final int y;

    Engine(int x, int y) {
      this.x = x;
      this.y = y;
    }
  }

  public class Car {
    private final Engine engine;

    public Car(int x, int y) {
      this(new Engine(x, y));
    }

    Car(Engine engine) {
      this.engine = engine;
    }
  }

  public class FastEngine extends Engine {
    private final double a;
    private final double b;

    FastEngine(int x, int y, double a, double b) {
      super(x, y);
      this.a = a;
      this.b = b;
    }
  }

  public class FastCar extends Car {
    public FastCar(int x, int y, double a, double b) {
      super(new FastEngine(x, y, a, b));
    }
  }