【问题标题】:I need advice on if my abstract class should be an interface (or vice versa)我需要关于我的抽象类是否应该是接口的建议(反之亦然)
【发布时间】:2020-02-25 13:05:24
【问题描述】:

我的 JavaFX 游戏中有一个继承层次结构建模实体。我的游戏中有 4 种敌人类型,但是它们只需要 Entity(抽象类)中方法的默认实现 + 1 个额外的方法,其中每个敌人将提供不同的实现。以后也不会再有敌人了。所以从这个背景来看,我认为 Enemy 应该是一个界面。

所以我的问题是,我假设 Enemy 应该是抽象类的接口是否正确?

这是我的类图(目前以敌人为抽象类):

【问题讨论】:

  • 如果 Enemy 是一个接口,它不能再扩展 Entity,因为它是一个抽象类。
  • @Héctor Enemy 不会扩展实体,而是单个 Enemy 类型会
  • 在这种情况下,你的敌人可能不是实体。
  • 在这种情况下,无论你在哪里需要一个 Enemy,你都不能使用实体方法,只能使用 Enemy 方法。
  • @Héctor No. 每个 Enemy 类型都将从 Entity 扩展,但实现 Enemy 接口

标签: java oop inheritance


【解决方案1】:

在我的编码经验中,每当我依赖抽象类来实现抽象时,我总是被时间证明是错误的。通常,在 OOP 中,一个类对于不同的消费者来说可能是不同的东西,因此,为了具有这种灵活性并避免由于类只能有一个父类这一事实而受到未来的限制,我了解到抽象应该始终是接口.

另一方面,抽象类用于为不同的接口实现提供通用功能,但即使在这种情况下,我也会尝试“支持组合而不是继承”。

所以,我的建议是始终对接口进行编程。

【讨论】:

    【解决方案2】:

    选择接口而不是抽象类总是好的,因为它启用了您的应用程序的extension

    在 Java-8 之前,抽象类是一种提供共享部分实现的方法,就像之前 Java-8 接口不能有方法定义一样。

    在 Java-8 中,接口具有允许定义共享实现的默认方法。

    因此,我的建议是在此处使用接口并提供默认方法。如果您需要提供合同之外的一些额外实现,您可以随时选择抽象实现或具体实现。

    在您的情况下,实体的任何表示都应由接口支持。

    所以,您的图表如下所示

    interface Entity extends cloneable{
    //...
    }
    
    interface Enemy extends Entity{
    //...
    }
    
    interface User extends Entity, Serializable{
    //...
    }
    
    class Player implements  User {
    //...
    }
    
    class Dragon implements Enemy{
    //...
    }
    

    【讨论】:

    • 经过深思熟虑,在某些情况下我只知道一个对象是否是一个敌人。如果在这种情况下 Enemy 是一个接口,我将无法访问从 Entity 继承的急需的方法。
    • 好吧!实体也应该是一个接口。这就是我所说的设置合同部分的地方,任何定制都应该通过实现接口在更具体的实现中完成。例如。敌人,用户都是实体类型,但并非所有用户都有相同的行为,也不是所有敌人都有相同的行为,但它们具有某些共同的属性(应该在界面中)。任何行为差异都应该在具体实施中。
    • 我明白你的意思。但是,在我的例子中,Entity 抽象类确实为用户和所有不需要覆盖默认实现的敌人提供了默认实现
    • 因此,您可以在 java-8 及以后的接口中提供默认 impl。你真的看过我的回答吗?
    • 是的,我阅读了您的回答,但是当作为抽象类已经提供默认实现时,将实体从抽象类转换为接口有什么好处
    猜你喜欢
    • 2010-10-03
    • 2011-03-19
    • 2021-05-08
    • 2017-03-27
    • 2013-10-25
    • 1970-01-01
    • 2016-08-13
    • 1970-01-01
    • 2023-03-08
    相关资源
    最近更新 更多