试图根据具体情况压制覆盖是错误的吗?

时间:2012-01-16 21:34:21

标签: oop class inheritance architecture override

我理解为什么通过方法重写实现的多态性非常有用。我问在某些情况下,当多态对象作为参数被接收时(而不是在它的类被定义时),可能会出现什么问题(如果有的话)。

类汽车描述了汽车的行为。 “FlyingCar”类描述了可以变换和飞行的汽车的行为。

我从某处收到了Car类或其子类的对象。我无法控制他们传给我的东西。

我知道由于我的图形引擎的技术限制,我无法显示飞行汽车。或许我希望玩家在不使用飞行能力的情况下完成特定任务。因此,我想通过让它看起来像是Car类的对象来简单地禁用汽车的飞行能力。我在考虑using downcasting,但它似乎不起作用。

这可能是不可能的,但如果我找到一种方法用我使用的语言来做,那么它的设计是不是很糟糕?如果是这样,为什么,又有什么选择?

我不能使用类似复制构造函数的东西从我收到的类中创建类Car的对象,因为所有数据的复制过于昂贵(Car对象很大)。

谢谢!

编辑:

我想避免在这个问题中选择特定的语言。一旦我选择了一种语言,答案很可能是“技术上不可能”,或“它可能,但所需的黑客过于危险”,等等。

我想了解这是不好的设计,原因与某种语言支持它的能力无关。

4 个答案:

答案 0 :(得分:1)

我的意见一般都不会。

原因在于,即使你能够以某种方式使你的FlyingCar表现得像从此时开始就是一辆Car,它仍然已经上运行,就好像它是一辆FlyingCar,可能不再适用于汽车的有效状态。

也许你的图形引擎无法显示FlyingCar是因为它使用了纹理。但有人已经在其上调用了load_appropriate_textures方法,它已将纹理数据存储在其中。如果你再次拨打load_appropriate_textures,将FlyingCar更改为Car可能会改变发生的情况,但FlyingCar不会覆盖render_car方法,只会将数据放在render_car找到它的位置。因此,组织中的其他一些糟糕的程序员最终会尝试调​​试Car无法使用有关FlyingCar纹理的错误消息进行渲染的原因。

也许在这个特定情况下不会发生这种情况。但它可以。有人可以稍后以引入此类问题的方式修改Car和FlyingCar。

一般来说,对于FlyingCar"好像"它是一辆汽车,你真的必须再次重复所有初始化(和后续修改)。通常不可能重复以后的修改(因为它们没有记录),重复初始化只不过是构建一辆新车。

所以看起来似乎"一般来说"这是一个坏主意。在任何特定情况下,如果你能找到一种方法,也许你会认为它是可以接受的。程序员每天都会妥协,它会发生。但是,如果不能完全通用地做到这一点,那么你总是冒着以后对Car和/或FlyingCar做出完全合理的改变的风险,这会使你的黑客不再有效。

实际上,听起来像FlyingCar需要具有禁用其飞行功能的功能。这样的事情总是很难在事后坚持下去。

答案 1 :(得分:0)

您可以使用composition instead of inheritance(听起来您的Car对象需要重构为更小的类:the Car object is huge)。

Car对象可以包含一个使其具有飞行能力的组件。要禁用汽车的飞行能力,您只需暂时(或永久地,如果需要)从Car对象中删除飞行组件。

答案 2 :(得分:0)

通常,当我们创建FlyingCar时,我们会确保以正常工作的方式扩展Car。希望我们只依赖Car承诺保持不变的Car界面;如果我们还依赖Car中的其他代码,我们就会这样做,因为我们拥有代码。

另一方面,这不适用于相反的方向。当有人拿飞车试图修改它以将其用作汽车时,无论用户多么小心,都无法保证不会破坏。毕竟,FlyingCar只承诺如果按原样使用,它将表现为Car的变体; 在某人试图从中取出一些碎片后,它会表现为Car。

例如,FlyingCar可能在构造时修改了各种控件的功能。如果它的方法被禁用,它将不会成为Car;它会被打破。

答案 3 :(得分:0)

直接回答这个问题:是的,这是错误的,因为禁止传递某些子类会违反Liskov Substitution Principle

你需要这样做的事实是一种强烈的气味,耐火材料可能是有序的......