使用继承来改变超类的接口

时间:2011-04-23 20:37:43

标签: java design-patterns inheritance interface

我来自网络开发背景。我最近一直在玩一些Java,并且遇到了以下问题,这些问题似乎源于严格的接口和数据类型,它们是Java的一部分而不是PHP。

我正在使用现有的物理引擎(Phys2D)开发各种游戏。此物理引擎具有由Body管理的World个对象,并且随着世界步进而对其施加各种力。对于游戏中的AI而言,身体具有颜色(以便可以感知它们)非常重要,但物理引擎不支持这一点,因此我创建了一个子类,并扩展了Body类包括这个 - http://pastebin.com/1nLYWg3w。现在,当我创建这些Body个实例时,我可以从World获取它们并获取它们的颜色。

然而,Netbeans说的是

cannot find symbol
    symbol:   method getColour()
    location: class net.phys2d.raw.Body

因为物理引擎接口返回的Body对象不包含此方法。我知道,在运行时,所有传递给Body的{​​{1}}对象实际上都是World类型的对象,因此将使用此方法在他们的界面中定义。

如何将颜色附加到ColouredBody个对象,而不会产生可怕的下划线和警告?我知道我可以改变Phys2D本身但是,除了潜在的许可限制(许可证说你可以使用Phys2D这样做),我被告知这是不好的做法。

3 个答案:

答案 0 :(得分:2)

如果您在运行时知道所有Body个对象实际上都是ColouredBody,那么您可以将这些对象转换为ColouredBody并调用getColour

Body body = ...;
ColouredBody colouredBody = (ColouredBody) body;
colouredBody.getColour();

答案 1 :(得分:1)

您可以转换为具体类型:

ColouredBody cbody = (ColouredBody) body;

最好只是为了避免问题,你可以检查一下是否真的:

if (body instanceof ColouredBody) {..}

请注意,向下转换(从更一般到更具体的类)通常被认为是一种不好的做法。

如果可能,您可以尝试使用World扩展ColouredWorld并覆盖返回Body的方法以返回ColouredBody(并且还将正文保留在适当的位置)收集),但根据复杂程度,这可能是一种过度杀伤。

答案 2 :(得分:1)

实际上,我认为将color属性添加到引擎本身的Body类是非常好的设计。

如果您不能这样做或者不想这样做,您只需将Body个实例转换为ColouredBody,然后再使用它们:

((ColouredBody)body).getColour();

这告诉编译器“我知道body实际上是ColouredBody的一个实例,所以让我像使用它一样” - 但如果事实证明不是在任何时候,你会获得ClassCastException