Java 使用接口的默认方法实现方法-矛盾? 介绍

Java 使用接口的默认方法实现方法-矛盾? 介绍,java,inheritance,interface,java-8,default-method,Java,Inheritance,Interface,Java 8,Default Method,我在这里读过多篇关于实现接口和抽象类的文章。我特别发现了一个我想在这里链接的问题-,它涉及同样的问题。作为公认的答案,建议在可能的情况下使用接口的默认方法。但下面的评论说明了我的问题:“这个功能对我来说更像是一个黑客。” 已经引入了默认方法,以使接口的实现更加灵活-当接口发生更改时,在实现类中不一定需要(重新)编写代码。因此,使用一个接口的默认方法只是为了在所有实现类中实现一个方法——quote:“对我来说更像是一个黑客” 我考试的例子: 课程概述: Item-所有项的抽象超类 水-消耗品 石

我在这里读过多篇关于实现接口和抽象类的文章。我特别发现了一个我想在这里链接的问题-,它涉及同样的问题。作为公认的答案,建议在可能的情况下使用接口的默认方法。但下面的评论说明了我的问题:“这个功能对我来说更像是一个黑客。”

已经引入了默认方法,以使接口的实现更加灵活-当接口发生更改时,在实现类中不一定需要(重新)编写代码。因此,使用一个接口的默认方法只是为了在所有实现类中实现一个方法——quote:“对我来说更像是一个黑客”

我考试的例子: 课程概述:

  • Item-所有项的抽象超类
  • 水-消耗品
  • 石材-非消耗性物品
  • 消耗品-与消耗品项的某些方法的接口(这些方法必须由所有实现类重写)
将这些因素结合起来:

水是一种消耗品和工具;石头也是一种物品,不能作为消耗品

我的考试 我想实现一个所有项目都必须实现的方法。因此,我在类项中声明签名

protected abstract boolean isConsumable(); 
//return true if class implements (or rather "is consumable") Consumable and false in case it does not
快速编辑:我知道instanceof可能会解决这个特定的例子——如果可能的话,考虑一个更复杂的例子,首先需要实现这个方法。(感谢Sp00m和尤金)

现在我有几个选择:

  • 在Item的每个子类中手动实现该方法(在扩展应用程序时,这绝对是不可能的)
  • 如上所述,在扩展应用程序时,这将是不切实际或效率极低的

  • 将接口内部的方法作为默认方法实现,这样可消耗类就已经实现了超类项所需的方法
  • 这是另一篇文章推荐的解决方案——我看到了以这种方式实施它的好处:

    Quote—“这个新特性的好处是,在您被迫使用抽象类来实现方便的方法之前,这样就可以将实现者限制为单一继承,现在您可以拥有一个真正干净的设计,只需接口,只需程序员承担最少的实现工作。”

    但在我看来,它似乎仍然与我在介绍中提到的默认方法的原始想法相矛盾。此外,当扩展应用程序并引入更多对所有耗材共享相同实现的方法时(如示例方法
    isConsumable()
    ),接口将实现几个默认方法,这与接口不实现实际方法的想法相矛盾

  • 引入子超类而不是接口-例如,类作为Item的抽象子类和Water的超类
  • 它提供了为Item中的方法编写默认大小写的机会(例如:
    isConsumable()//return false
    ),然后在子超类中重写它。这里出现的问题是:当扩展应用程序并引入更多的子超类(作为可消耗类)时,实际项目将开始扩展多个子超类。这可能不是一件坏事,因为对接口也必须这样做,但这会使继承树变得复杂-例如:一个项现在可能扩展一个子超类ALayer2,它是ALayer1的子超类,ALayer1扩展了项(layer0)

  • 引入另一个超类(因此与Item相同的层)-例如,作为抽象类的类将是另一个水超类。这意味着水必须延伸到物品和消耗品
  • 此选项提供了灵活性。可以为新的超类创建一个全新的继承树,同时仍然能够看到项的实际继承。但我发现的缺点是在实际类中实现了这种结构,并在后面使用了这些结构-例如:我如何才能说:消耗品是一个项目,而消耗品可以有不用于项目的子类。整个转换过程可能会引起头痛-比方案3的结构更有可能

    问题: 实施这种结构的正确选择是什么

    • 这是我列出的选项之一吗
    • 这是它们的变体吗
    • 还是我还没有考虑过的另一个选择
    我选择了一个非常简单的例子——在回答这个问题时,请记住未来实现的可伸缩性。提前谢谢你的帮助

    编辑#1 Java不允许多重继承。这将影响选项4。 使用多个接口(因为您可以实现多个接口)可能是一种解决方法,不幸的是,默认方法将再次成为必要,这正是我最初一直试图避免的实现类型

    我缺少选项5(或者可能我没有正确阅读): 在
    本身中提供方法

    假设消耗品可通过
    消耗品
    -界面识别,以下是我无法推荐您列出的大多数要点的原因:
    第一个(即在每个子类中实现它)对于像
    这个实例这样简单的消耗品
    来说太难了。第二个也许可以,但不是我的第一选择。第三个和第四个我完全不能推荐。如果我能给出一个建议的话,那就是可能要再三考虑继承问题,永远不要使用中间类
    
    public final boolean isConsumable() {
      return this instanceof Consumable;
    }