java - Java 中可接受的避免多重继承缺失的方法

标签 java oop inheritance multiple-inheritance

我正在制作一个游戏。我有一个实体类,它是一对 x,y 坐标以及宽度和高度。

我想将此实体类子类化为几个新类,以添加功能组的组合。我想添加几个“组”功能:

Moveable {
    public float getVelocityX();
    public void setVelocityX(float velocityX);
    public float getVelocityY();
    public void setVelocityY(float velocityY);
    public void moveRelative(float dx, float dy);
    public void setPosX(float posX);
}

Rotatable {
    public void setAngularVelocity(float degreesPerSecond);
    public void setAbsoluteAngle(float angle);
}

Resizable {
    void setAbsoluteSize(int width, int height);
    void setRelativeSize(int widthGrowFactor, int heightGrowFactor);

    public void setWidth(float width);
    public void setHeight(float height);
}

...以及更多(可更新、可绘制、可碰撞)。

某些实体可以旋转/绘制,但不能移动/碰撞/更新/调整大小:“静态”不可触摸的事物,例如背景动画(云、太阳、星星)。

某些实体可以移动/旋转/绘制/更新/碰撞/调整大小:玩家角色和怪物。

某些实体只能绘制:游戏的 HUD。

某些实体可以移动/绘制/更新/碰撞,但不能旋转/调整大小:例如枪声。

如您所见,我需要组合上述功能,并且可以通过一些多重继承轻松解决。

为什么不使用您要求的接口(interface)来实现呢?因为这会让我为所有方法复制/粘贴大量代码,并且创建新类型的实体类将永远引入复制/粘贴。

您可能会问,为什么我不创建一个可以完成所有操作的子类,然后重写不应该与空方法一起使用的方法,或者在无效方法中抛出 UnsupportedOperationException?尽管每个方法中只有一行,但这仍然是复制/粘贴。只能 move() 的实体最终可能会出现 50 个带有“throw new UnsupportedOperationException();”的方法。这是 Not Acceptable 。

如果您建议适配器模式,我希望您能发布一个示例,说明适配器模式如何执行此类操作(我已经对此进行了辩论)。

如果您建议组合,请解释我将如何访问 protected 字段。

谢谢!

最佳答案

正如罗曼在评论中所说:

Java 确实允许接口(interface)的多重继承。如果您所需要的只是继承 is-a 关系和一组有保证的方法来与对象进行通信,那么这非常有效。

只能继承一个(无论是否抽象)(以及需要的许多接口(interface))。这是为了避免“菱形继承(钻石问题)”的并发症——网络搜索该短语以了解更多信息。如果您确实需要重用多个来源的逻辑,通常的解决方法是在实用程序类中定义其他共享行为,并将您的类委托(delegate)给该实用程序类的实例。是的,这是一个 has-a 关系,而不是 is-a 关系,但由于 is-a 可以抽象为一个接口(interface),因此您可以获得所需的组合行为的最终外观。 (与菱形继承(钻石问题)不同,这迫使您明确决定要调用哪个实现。)

关于java - Java 中可接受的避免多重继承缺失的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21068902/

相关文章:

java - 如何将对象从一张 map 放到另一张 map 上?

c++ - 如何访问 child 的 protected 变量

c# - 覆盖属性的访问器

java - 将基于 2d 图 block 的 iPhone 游戏移植到 Android。

java - MSSQL Server 2005-JDBC连接

java - Exception.Message 属性应该直接显示给用户吗?

.net-3.5 - 派生类型不能隐式转换为基接口(interface)

java - 设计模式处理具有许多成员的类(不是构建器)

java - 如何每 15 分钟从 Cassandra 获取一次数据,但只返回已更改的信息?

Java以接口(interface)作为参数覆盖抽象类方法