为什么这些接口不能相互继承?

时间:2017-05-06 22:31:54

标签: java oop inheritance interface

我发布了question关于我在Effective Java中读到的接口和建议。我得到了我想要的答案,一切都很好,直到今天下午我签到SO时,还有一条评论说

  

这些接口不应该相互继承。

我问为什么,但仍然没有得到答案。有人可以解释为什么你不允许这些接口继承?你会如何解决它,仍然保持答案中提供的相同功能?

public interface GameObject {
    void viewDetails();
}

public interface Weapon extends GameObject {
    void attack();
}

//A weapon is not the only item reloadable. A container could be refilled. 
public interface Reloadable extends GameObject {
    void replenish (final int amount);
}

我看到这些接口不能继承的唯一原因是GameObject接口的简单性。它不提供toString无法完成的任何功能。但是,它只是我游戏的开始阶段,GameObject当然会扩展。

3 个答案:

答案 0 :(得分:0)

我认为你过分担心你的设计的纯度,以至于你关注细节而不是花时间富有成效,也就是写你的游戏。

无论哪种方式都没有太大的区别。

通常,“GameObject”(以及名称以“Object”结尾的任何内容)是一个类,如果需要则是抽象类,但不是接口。命名接口“SomethingObject”的唯一原因是接口还扩展(或通过聚合暴露)CloseableAutoCloseable)接口,这意味着任何引用它的人都可能会破坏它。所以,如果你采用这种方法,其余的问题都会得到简单的回答:接口武器可能不会扩展GameObject,因为接口可能不会扩展类,Reloadable也是如此,我们就完成了。

现在,如果你坚持使用“GameObject”界面,你仍然可以选择为每一个附加特征扩展它,或者保持每个附加特征分开,而不扩展“GameObject”。这两种方法都有效。

如果你保证,如果你发誓所有对你而言都是珍贵的东西,那么永远不会有一个也不是游戏对象的Reloadable,那么你可以继续使用Reloadable扩展GameObject。但你真的需要吗?通常的做法是我们更喜欢使用接口来增加继承树的分支程度,而不是将继承树变成图形。 (并非它永远不会发生,但很少发生。)因此,我们通常不这样做。但如果你这样做,那就不是世界末日了。

另请注意,当我们从另一个接口扩展一个接口时,我们(并非总是如此)通常会扩展名称。所以,你的武器将是WeaponGameObject,你的Reloadable将是ReloadableGameObject。

另请注意,接口继承很少(如果有的话)必要;你可以使Reloadable成为一个独立的界面(不扩展GameObject),你可以让Reloadable包含一个GameObject getGameObject()方法,从而基本上将这两个实体连接在一起。然后,您的BFG9000ReloadableGameObject类可以实现Reloadable和GameObject,并将getGameObject()实现为return this;

答案 1 :(得分:0)

进行真正的域名分析。您会发现replenish行为ReplenishableWeapon不一定是GameItem,并且在补充它为Vehicle时可能无关紧要。 public interface Weapon extends GameItem { public class ChargeGun implements Replenishable, Weapon {... public class FlyingCarpet extends GameItem implements Replenishable, Vehicle {... 可能还需要补货。也许像是

gun.replenish();

通常有一个类做接口mixins比接口继承它们更好。这取决于域以及您如何建模。尽可能多的你想要

replenish(Replenishable Replenishable);

不是

 <Ellipse x:Name="myEllipse1" Width="300" Height="150" Fill="DarkGreen" />

因人而异。

答案 2 :(得分:0)

在这里同意迈克:可能不是你应该担心的阶段。

对于游戏开发建模的世界&#39;通常避免使用面向对象的原则。这是由于对象和性能原因的强烈耦合。非常先进的游戏引擎不会为世界上的实体创建特定的类。

如果您对更精细的细节感兴趣, 看一下这个: http://entity-systems-wiki.t-machine.org/