Каков наилучший способ решить эту проблему Java наследования? - PullRequest
0 голосов
/ 18 января 2019

Первый класс авто:

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 голосов
/ 18 января 2019

Предлагаю создать завод двигателей.Помните принцип « Single Responsibility » ( SOLID ).

В реальной жизни вы не строите двигатель внутри автомобиля.Вы делаете это отдельно.Иногда на другом заводе.Двигатель устанавливается в машине на конвейере.

Это дает вам больше гибкости как на заводе, так и в коде.

В дальнейшем я предлагаю реализовать шаблон строителя - если в автомобиль будет установлено больше деталей.

PS игнорируют "статические" значения - я просто добавил их, чтобы избежать предупреждений 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;
    }
}
0 голосов
/ 18 января 2019

Верните конструкцию двигателя обратно в конструктор автомобиля. Если создание движков занимает больше, чем вызов конструктора, переместите его в статическую функцию конструктора.

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));
    }
  }
0 голосов
/ 18 января 2019

Хотя я согласен с комментариями о том, что вопрос сформулирован недостаточно хорошо, я дам вам решение. Не стесняйтесь добавлять дженерики, чтобы сделать его более красивым.

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!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...