【问题标题】:abstract classes and interfaces best practices in javajava中的抽象类和接口最佳实践
【发布时间】:2010-12-28 06:47:48
【问题描述】:

所以你有一个接口和一个实现接口中方法子集的抽象类。您还有一些类继承了抽象类并提供了抽象类没有提供的方法的实现。

那么这里的最佳做法是什么?我说的是这样的问题:

1) 抽象类应该实现接口还是它的子类?应该每节课吗?在我看来,只有抽象类应该。当然,所有的类都可以实现接口,但这似乎是多余的,因为抽象的子类将“继承”接口,因为它们扩展了抽象类。

2) 既然抽象类实现了接口的一部分,它是否也应该为它没有实现的方法声明抽象方法?在我看来这是对的,但在某种程度上这似乎是多余的,因为抽象的孩子需要实现这些方法才能编译。

那么,您认为最佳实践的理由是什么?问题归结为:我们有一个接口,它定义了我们想让某些类做什么,我们在接口中有一个定义常见行为的方法子集,我们有几种不同的方法来定义不常见的行为。最好的布置方式是什么?

【问题讨论】:

    标签: java oop inheritance interface abstract-class


    【解决方案1】:

    这里应该对您有所帮助的原则 id DRY:不要重复自己 (http://en.wikipedia.org/wiki/Don%27t_repeat_yourself)。

    在这种情况下,DRY 意味着您不应该做不必要的工作。

    所以对于您的第一个问题,抽象类应该实现接口,因为它可以避免您在每个具体类中重复“实现 X”子句。

    至于第二个问题,在实现它的抽象类中重复接口方法是没有意义的。这是多余的工作。此外,当接口演变/更改时,您将需要更改抽象类中的对应(抽象)方法,这是一个令人头疼的问题。在某些时候,您会错过更新某些方法,而具体类将需要徒劳地实现这些。

    【讨论】:

    • +1,我要补充一点,如果我个人看到一个实现 Foo 并扩展 AbstractFoo 的具体类,我的第一直觉会是 Foo 和 AbstractFoo 甚至可能不相关。随着名称变得不那么明显,更多的混乱。
    • 程序不断发展(因为您添加了新功能,您修复了错误等等),从而导致底层工件(类、接口、方法...)发生变化。例如,您可能决定一个方法需要一个附加参数,因此您必须在声明接口中更改其签名。
    【解决方案2】:

    抽象类应该实现接口,并提供常用成员函数的具体实现。 IIRC它不应该需要为它没有实现的元素声明抽象方法,因为这些被假定需要由子类来实现。

    【讨论】:

      【解决方案3】:

      最灵活的编程方式是:

      1. 提供接口
      2. 提供实现接口的抽象类
      3. 提供从抽象类扩展或从另一个类扩展并实现接口的具体类
      4. 始终(除非您不能)将变量/参数/常量声明为接口,而不是抽象类或具体类

      让具体类实现接口是没有意义的(稍后会详细介绍)。 让抽象类重复接口中的抽象方法是没有意义的。

      通过执行 #4,您可以确保可以使用所有实现接口的类 - 如果您要使用抽象类,则无法使用实现接口但不扩展抽象类的类。

      (后半部分)

      让抽象类和具体类实现接口的一个论据是,如果您稍后更改具体类以不再扩展抽象类,那么您可能会忘记也实现接口,在某些情况下情况下,可能会在编译器不抱怨的情况下破坏代码。我不知道我对这个论点有何感想。

      【讨论】:

        【解决方案4】:

        接口方法是隐式抽象的,所以如果一个抽象类实现了一个接口,就不需要满足抽象类中的接口契约。抽象接口在技术上是合法的,但也是多余的。只要所有子类都实现接口,抽象类实现接口就可以了,但抽象类不应该包含实现的方法。

        接口方法是特定于实现的(对于实现类来说是唯一的),而抽象状态和行为意味着是通用的,或者在实现之间共享。将接口方法实现为通用功能将是矛盾的。

        关键问题是您打算如何处理接口实现?如果基本接口除了定义一个额外的契约之外没有用于任何事情,我会说简单地将抽象方法添加到抽象类,否则接口是多余的开销。如果您发现一个用例希望访问接口方法,但不一定是通用功能,那么也许接口是值得的。

        【讨论】:

          【解决方案5】:

          你有比抽象类或其子类更多的接口实现吗?你的设计需要界面吗?否则,界面对您的设计毫无贡献,我建议您干脆去掉它。

          当涉及到明确的问题时,抽象类应该实现接口。扩展抽象类的类不应该。

          您不应该在接口中已经存在的抽象类中多余地声明抽象方法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-09-03
            • 1970-01-01
            • 1970-01-01
            • 2014-02-05
            • 2020-10-20
            • 2019-04-08
            • 2011-03-17
            相关资源
            最近更新 更多