我理解为什么通过方法覆盖实现的多态性是非常有用的。我在问,在某些情况下,当多态对象被作为参数接收时(而不是在定义它的类时),如果试图抑制它,可能会出现什么问题。
class car描述了汽车的行为。FlyingCar类描述了一辆可以变形和飞行的汽车的行为。
我从某个地方收到Car类或它的子类的对象。我无法控制他们传给我的东西。
我知道,由于我的图形引擎的技术限制,我不能显示飞行的汽车。或者我想让玩家在不使用飞行能力的情况下完成特定的任务。因此,我想简单地禁用汽车的飞行能力,让它看起来像是Car类的对象。我在想using downcasting,但它似乎行不通。
这可能是不可能的,但如果我找到了一种用我使用的语言做到这一点的方法,这是不是很糟糕的设计?如果是这样,为什么,还有其他选择吗?
我不能使用复制构造函数从我收到的对象中创建Car类的对象,因为由此产生的复制所有数据的开销太大( Car对象很大)。
谢谢!
编辑:
我想避免在这个问题中选择特定的语言。一旦我选择了一种语言,答案很可能是“这在技术上是不可能的”,或者“这是可能的,但所需的黑客攻击太危险了”,等等。
我想知道这是否是糟糕的设计,原因与某种语言支持它的能力无关。
发布于 2012-01-17 00:03:59
我的意见通常是否定的。
原因是,即使你能以某种方式使你的FlyingCar的行为只会像它是一辆汽车从这一点上,它仍然是已经在上操作,就好像它是一辆FlyingCar,并可能不再是一个有效的状态为汽车。
也许你的图形引擎不能显示FlyingCar的原因是因为它使用的纹理。但是已经有人在它上面调用了一个load_appropriate_textures
方法,这个方法已经在里面存储了它的纹理数据。将FlyingCar更改为汽车会改变再次调用load_appropriate_textures
时发生的情况,但FlyingCar不会覆盖render_car
方法,它只是将数据放在render_car
可以找到的地方。因此,您组织中的其他一些糟糕的程序员将最终尝试调试为什么汽车无法渲染,并显示一些关于FlyingCar纹理的错误消息。
也许在这个特殊的案例中不会发生这种情况。但这是可能的。有人可以在以后修改Car和FlyingCar,从而引入这种问题。
一般来说,对于FlyingCar“就好像”它是一辆汽车,你真的必须再次重复所有的初始化(和后续的修改)。重复后来的修改通常是不可能的(因为它们没有被记录下来),并且重复初始化只意味着构造一辆新车。
所以看起来“总的来说”这是个坏主意。在任何特定的情况下,如果你能找到这样做的方法,也许你会决定它是可以接受的。程序员每天都会做出妥协,这种情况时有发生。但如果不能完全通用性地做到这一点,那么你总是会冒着以后对Car和/或FlyingCar做出完全合理的更改的风险,从而使您的黑客攻击不再起作用。
真的,听起来FlyingCar需要具备禁用其飞行功能的功能。像这样的东西总是很难在事后固定下来。
发布于 2012-01-16 22:11:49
您可以使用composition instead of inheritance (听起来您的Car
对象无论如何都需要重构为更小的类:the Car object is huge
)。
然后,Car
对象可以包含一个组件,该组件使其具有飞行功能。要禁用汽车的飞行能力,您只需临时(或永久,如果需要)从Car
对象中移除飞行组件。
发布于 2012-01-17 00:29:12
通常,当我们创建一个FlyingCar时,我们会确保以一种正确工作的方式扩展Car。希望我们只依赖Car的接口,Car承诺保持不变;如果我们还依赖于Car中的其他代码,我们这样做是因为我们拥有这些代码。
另一方面,这在相反的方向上不起作用。当有人试图将FlyingCar改装成汽车时,无论用户多么小心,都不能保证它不会坏掉。毕竟,FlyingCar只是承诺,如果按原样使用,它将表现为汽车的变体;而不是说,在有人试图从它身上取出一些部件后,它将表现得像汽车一样。
例如,FlyingCar可能在构造时修改了各种控件的函数。如果它的方法被禁用了,它就不会变成汽车;它只会坏掉。
https://stackoverflow.com/questions/8886568
复制相似问题