【问题标题】:Add methods to classes without breaking implementations在不破坏实现的情况下向类添加方法
【发布时间】:2014-06-15 10:21:11
【问题描述】:

假设我有 2 个名为 class Cowclass Pig 的课程。

他们都实现了interface Animal

对于interface,只有两个方法称为public void eat()public void speak()

一切都很好。但是,虽然这似乎很好地利用了interfaces,但我认为如果我需要向这个interface 添加方法,实现会中断,即我需要在这些类中实现新方法,这打破了“关闭-打开原则”。

所以我想,除了interface,我也会使用abstract类,如果以后需要我需要添加新的方法。

例如,public class Cow extends ... implements Animal

这听起来是个不错的计划(如果不是,请纠正我)。

但问题是,如果这些类extend 已经是其他类怎么办?在这种情况下,我无法扩展 2 个类。

所以我的问题是:

有没有一种模式可以让我声明一个常见的interface 相关的类,同时保留在其中添加新方法的能力 不打破“封闭开放原则”的未来 中断实现?

【问题讨论】:

标签: java design-patterns design-principles


【解决方案1】:

对于 Java 8,有 default methods

public interface Animal {

    void eat();
    void speak();
    default void sleep(){}

}

现在您的Animal 必须覆盖eatspeak,但可以选择覆盖sleep

使用 abstract class 的 Pre Java 8 是防止必须实现每个 interface 方法的常用方法。正如您所指出的,这不适用于多重继承,因此不能用于解决所有情况。

附:不要声明interface 方法public,这是所有interface 成员的默认可见性。

【讨论】:

  • 感谢您的回复。那么,当一个 API 设计者需要在下一个版本中添加新方法时,他将如何去做(如果该类已经扩展了另一个类)?您能否为此引用我的示例(Java 8 之前)?谢谢。
  • @Unheilig 举个例子,参见 Number 类,其中 intValuelongValue 声明为抽象方法,而 byteValueshortValue,自 Java 1.1 起添加,提供作为具体的实现。
  • @GOTO0 谢谢。但是在这种情况下,Number 被声明为abstract 类而不是interface 并且通过具体实现您的意思是作者在abstract 类中声明abstract concrete 方法?这是可以理解的,但如果它 (Number) 是 interface 并假设子类已经 extend 另一个类,这不会起作用,对吧?
  • @Unheilig 不,那行不通。在这种情况下,建议创建一个新接口,使用新声明扩展旧接口,新的声明只能用于新代码。
  • @Unheilig 我找不到我对上述主张的参考,但这里有一个解释这个想法的官方教程:docs.oracle.com/javase/tutorial/java/IandI/nogrow.html
【解决方案2】:

在 Java 8 中,接口可以为此目的定义 default methods

【讨论】:

    猜你喜欢
    • 2021-04-28
    • 2021-09-05
    • 2011-11-26
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多