java - 权利继承顺序

标签 java oop inheritance design-patterns

我们需要有轻型/重型汽车的实例和北极轻型/重型汽车的实例。不将 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();
}

最佳答案

在我看来,实现这种设计的最佳方法是仔细研究问题域。对我来说,看起来你那里有不止一个实体(汽车)。有 Engine、CarLights、Forecast,也许还有其他。 如果是这种情况,更好的设计是为模型中的每个实体提供类:

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 的优点之一是它允许您在代码中建模解决方案,以解决当前的问题。

例如,这种情况下的构图更加自然,它将紧密地反射(reflect)汽车的真实部件。

另外,还有这个:

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

所以这里的职责是:

引擎 - 预热和启动的代码

CarLights - 打开/关闭灯的代码

预测 - 要检查的代码

汽车和衍生品 - 将以上所有 3 个放在一起并使用它们的功能。

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

关于java - 权利继承顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39380097/

相关文章:

java - 如何在java中删除java映射值(不是键)?

java - 有条件地生成 10 个随机对

typescript - 继承自错误中断 `instanceof` 检查 TypeScript

oop - 在 View 模型之间传递状态

php - 如何在 POSTMAN Rest API 中测试 OOP PHP 函数

python - Python 中的访问器是否合理?

javascript - 在 Javascript ES6 的子类中扩展父类方法

java - Spring 致动器上的不同端口

java apache tomcat 没有检测到 jsp 文件,即使它存在

javascript - 稍后在不使用 .prototype 的情况下将其他功能添加到类中