我们需要有轻型/重型汽车和北极轻型/重型汽车的实例。不将ArcticCar代码复制到ArcticLight / HeavyCar中的正确继承(或合成方法)是什么?

class Car {
    startEnging() {
        turnOnPeripheralDevices();
        checkFuelLevel();
        // + other default actions. Some of them can be overrided in child classes to add specific actions
        log("engine started");
    }
    /* Common car stuff */
}

class LightCar extend Car {
    override startEngine() {
        log("light car prepare to start");
        parent.startEnging();
    }
    /* Basic light car stuff */
}
class HeavyCar extend Car {
    override startEngine() {
        turnOnLights();
        log("heavy car prepare to start");
        parent.startEnging();
    }
    override turnOnPeripheralDevices() {
        parent.turnOnPeripheralDevices(); //Car's default actions
        // additional actions for HeavyCars only
    }
    /* Basic heavy car stuff */
}

class ArcticCar extend Car {
    override startEngine() {
        warmUpEngine()
        wait10seconds();
        log("arctic mode: warming up engine");
        parent.startEnging();
    }
    /* A lot of common stuff for arctic cars. Can overwrite some common Car's functions */
}

class LightArcticCar extend **LightCar, ArcticCar** {
    override startEngine() {
        log("arctic ligh car prepare to start");
        parent.startEnging();
    }
    /* Arctic light car stuff. Can overwrite some specific LightCar's functions */
}
class HeavyArcticCar extend **HeavyCar, ArcticCar** {
    override startEngine() {
        if(checkForecast())
            parent.startEnging();
    }
    override turnOnPeripheralDevices() {
        parent.turnOnPeripheralDevices(); //Car's + HeavyCar's default actions
        // additional actions of HeavyArctic car
    }
    /* Arctic heavy car stuff. Can overwrite some specific HeavyCar's functions */
}

class Main {
    buggy = new LightCar();
    awdSUV = new HeavyCar();

    snowmobile = new ArcticLightCar();
    mobileLaboratory = new ArcticHeavyCar();
}

最佳答案

我认为,实现此设计的最佳方法是仔细研究问题域。在我看来,您那里有一个以上的实体(汽车)。有引擎,车灯,预测,也许其他。
如果是这种情况,更好的设计是为模型中的每个实体都具有类:

class Car {
   protected Engine engine;
   protected CarLights carLights;
   void start() {
      engine.start();
   }
}

class Engine {
    void start() { ... }
    void warmUp() { ... }
}

class CarLights {
   void turnOn() { ... }
}

class Forecast {
   void check() { ... }
}


层次将是:

class LightCar extend Car {
    // no code for start

    /* Basic light car stuff */
}

class HeavyCar extend Car{

    void start() {
        carLights.turnOn();
        log("heavy car prepare to start");
        parent.start();
    }

    /* Basic heavy car stuff */
}

class ArcticCar extend   Car {
    void startEngine() {
        engine.warmUp()
        wait10seconds();
        log("arctic mode: warming up engine");
        parent.start();
    }
    /* A lot of common stuff for arctic cars.
       Can overwrite some common Car's functions */
}

class HeavyArcticCar extend ArcticCar {
    Forecast f; // if it a component of a car. If not, then it should be a local variable in start()
    void start() {

        if( f.check())
            parent.startEnging();
    }
}


OOP的优点之一是,它允许您用代码建模解决方案,该解决方案可以解决当前的问题。

例如,这种情况下的构图自然得多,它将紧密反映汽车的真实组件。

另外,这是:

https://en.wikipedia.org/wiki/Single_responsibility_principle

因此,这里的职责是:

引擎-预热并启动的代码

CarLights-打开/关闭灯的代码

预测-要检查的代码

汽车和衍生工具-将以上三个全部放在一起并使用其功能。

最后,可以通过使Engine,CarLights和Forecast实现一个公共接口(如CarComponent)来进一步改进设计,因为它们具有相同的接口,它们都是汽车部件,并在Car类中使用CarComponent的列表。 。这将更加灵活,因为您可以更轻松地添加或删除组件。

09-05 04:19