继承与变化的实例?

时间:2012-07-06 23:14:17

标签: c# java oop

如果我对各种品牌的汽车进行建模,我会使用继承层次结构,还是仅使用不同的构造函数参数?

使用继承关联对象或仅重用同一个类的一般规则是什么?

对于汽车我可以做一些像新车(“保时捷”,“991”,“3.8”)或我可以有一个整体抽象的汽车超类,抽象的子类制造商,如“保时捷”,然后可能是一个类保时捷的每个型号?

6 个答案:

答案 0 :(得分:8)

如果您拥有所有汽车(或作用于该对象的方法)共享的一些属性,然后是每个品牌/型号的唯一属性(或方法),那么您希望使用继承。否则,只需改变实例即可。

我们只想说你想要所有汽车的这些属性:

  • 模型
  • 门数

在这种情况下,您不会想要创建一个类层次结构,因为它不会为您购买任何东西。

相反,如果你有两个"类型"汽车:普通汽车和赛车,只有赛车可以启用氧化亚氮(可能是这样做的一种方法),你需要一个Car类,RegularCar和RaceCar继承它。

如果您只是害怕必须始终将相同的参数传递给构造函数,则可以创建代表您调用构造函数的静态方法。这称为Factory method pattern

PS:我的例子真的刚刚脱颖而出。但我希望你能理解我想说的话:)。

答案 1 :(得分:3)

创建子类约为managing complexity,并将您的问题分解为更小,更简单的不同且不重叠的情况。如果你必须为所有汽车解决一些问题,并且你认为,这个问题对于保时捷来说是“特别”的,因为他们有一个普通汽车没有的额外备用引擎,你可以创造类似的东西

PorscheCar : Car
{
    Engine engine;
    Engine backupEngine;
}
NonPorscheCar : Car
{
    Engine singleEngine;
}

因此,在您决定创建一个可以解决问题的类之后,如果您在该问题中检测到多个案例,那么您可以并且决定独立解决,您可以为每个案例创建一个子类。您始终可以在不使用子类的情况下解决所有问题。问题在于,如果在创建子类时没有创建子类,我将很难正确地管理和组织代码。

您必须小心选择每个对象或类解决的每个问题。如果您希望您的保时捷打印如 保时捷 和没有 * 的普通车型,那么这并不意味着保时捷“行为”不同,你需要创建一个特定的子类。实际上表现不同的是你如何打印保时捷,所以你应该创建类似的东西:

Car
{
    Brand brand;
}
CarPrinter
{
    Car carToPrint;
    static CreatePrinter(Car car)
    {
        return car.Brand() == PorscheBrand() ? new PorscheCarPrinter(car) : new DefaultCarPrinter(car);
    }
}
PorscheCarPrinter
{
    Print();
}
DefaultCarPrinter
{
    Print();
}

因此,分为两种情况的问题是印刷汽车,而不是汽车本身的造型。

以更抽象的方式,您应该创建一个类来为您的域的每个概念建模。当您检测到由该域的特定概念建模并解决的责任是复杂的,并且您希望将其拆分为更小且不同且不重叠的情况时,则应为每个较小的问题创建子类。

在您的特定情况下,我不知道您的整个问题,但您不太可能需要为每个品牌的汽车创建子类,因为它们通常是一个单一的概念,只需要解决一个案例。

答案 2 :(得分:2)

单一类方法的问题在于,您使用相同的实例变量和方法来处理所有不同类型的Car

例如,汽车人可能拥有大多数其他汽车不具备的transform()方法。

我的意思是,理论上你可以为所有transform()定义一个Car方法,让不支持它的汽车抛出异常。但这比使用继承更麻烦。

继承还可以让你做一些像多态这样的奇特事情。例如,每辆车可能都有parallelPark()方法。但更高档的汽车可能有一个自动平行停车机制,不同于所有其他汽车。在这种情况下,您只需覆盖parallelPark()方法,Java将选择正确的方法。

答案 3 :(得分:2)

我会说这取决于逻辑依赖于制造商和型号等属性。如果不是,则执行new Car("Porsche","991","3.8")是有意义的,因为制造商和模型只是属性。但是,如果制造商和模型定义了一组其他属性或逻辑,那么类可能有意义。这样,您可以定义一个定义所有这些属性的new Car("Porsche","991","3.8", gearingRatios, topSpeed, price, etc)类,而不是每次想要保时捷991时都传递Porsche991

或者,如果PorscheVolkswagen汽车在Accelerate()方法中具有非常不同的逻辑,那么在逻辑部分扩展更多内容,那么而不是Accelerate()方法{1}}使用不可扩展的switch / case方法,可以使用继承。或者,如果Porsche需要Race()方法而Volkswagen s不需要,等等。

如果不知道您打算如何使用Car,很难将其概括为Car示例。

答案 4 :(得分:0)

对于像汽车这样的超类,更合适的子类是轿跑车,轿车和敞篷车。汽车模型应该是一个参数。

答案 5 :(得分:0)