Java 与内部实现的接口-好或坏
我正在做一个有很多someInterface-someInterfaceImpl对的项目。几天前,我有了一个想法(可能是受阅读一些目标c代码的启发),将默认实现作为一个内部类包含进来。 现在,一些同事(都比我有更多的java经验)看到了这个想法——反馈既震惊又惊讶(“这是可行的?”) 我在谷歌上搜索了一下,但没有找到太多证据证明这种“模式”(我个人喜欢): 和 您怎么看?尤其是在“默认”实现与接口紧密耦合的情况下 更新 我刚刚发现:Java 与内部实现的接口-好或坏,java,interface,coding-style,Java,Interface,Coding Style,我正在做一个有很多someInterface-someInterfaceImpl对的项目。几天前,我有了一个想法(可能是受阅读一些目标c代码的启发),将默认实现作为一个内部类包含进来。 现在,一些同事(都比我有更多的java经验)看到了这个想法——反馈既震惊又惊讶(“这是可行的?”) 我在谷歌上搜索了一下,但没有找到太多证据证明这种“模式”(我个人喜欢): 和 您怎么看?尤其是在“默认”实现与接口紧密耦合的情况下 更新 我刚刚发现: (请参阅接受的答案)接口的全部要点是将用户与实现分离(默认或
(请参阅接受的答案)接口的全部要点是将用户与实现分离(默认或非默认)。通过将实现作为内部类包含,可以克服这一问题。实际上,您没有保存任何代码行,API也变得杂乱无章。最终,您不得不对接口的用户隐藏内部类,比如将其设置为私有或默认范围,这可能是最好避免的。另外,如果您的默认实现需要更改,但您已将接口作为API的一部分发布,该怎么办。这是一个坏主意,因为它没有很多好处,是一种反模式 最后,如果您真的有一个默认实现,那么它可能应该是一个基类(而不是一个接口),而其他实现则扩展该类并重写行为 我认为这篇文章对一个类似的问题进行了有趣的讨论:
我同意上述答案,但在某些情况下,包括实施是合乎逻辑的,例如:
- 您正在编写匿名函数(当您的接口只有一个方法,并且您正在像函数语言中的匿名函数一样使用它时),这是正常的,但是很少
hasNext
始终返回true
)
我认为关键是默认实现不能依赖于接口之外的任何东西。不要使用外部类和接口,除非它们在接口的主体中被引用,也不要使用扩展默认值的外部类。这个接口变得比标准的接口概念稍微多了一点,但仍然是独立的
另一个关键点是,您不希望在一个.java文件中包含太多的代码,但也不希望包含太少的代码。如果默认实现需要更改,那么您可以删除一个包含新实现的版本,而不需要更改接口定义本身。如果要用作默认实现,也不需要隐藏该实现。我不认为按照OP描述的方式来做有什么好处,但我也不认为你提出的负面影响是非常可怕的——我只是觉得把它们放在一起,强制一个新的接口发行版来进行实现更改是没有意义的。我正要补充一个关于基本实现vs抽象vs接口的答案,你打败了我:-)太可怕了,也许不是。糟糕,是的。它打破了接口是未实现API的整个概念。如果没有其他内容,它会使接口的源代码可读性降低,因为它与默认实现混杂在一起,而默认实现应该对接口的用户隐藏。您是对的,但在我的特殊情况下,创建接口的唯一原因是测试能力(gwt with mvp模式)。因此,api永远不会被“发布”,而且很可能除了mock之外,再也不会有其他实现。除此之外,有人读过我提供的链接吗?似乎还有其他好处?!上面的Radio 2不是具有默认实现的接口定义,而是具有被覆盖的默认实现的
抽象类的扩展。请注意,由于提供了默认实现,因此它是作为抽象类
而不是接口
完成的。ModifyListener
接口没有默认实现。您已经创建了一个实现接口的匿名内部类,这就是我要说的。问题是关于内部类,他没有说明它是否是匿名的。这是一个要点:-)-但我不是在谈论匿名类。我说的是“combo.addModifyListener(new ModifyListener.Impl())”啊。我又读了一遍这个问题。不知怎的,我错过了最后一句话,谢谢你指出。
/** An interface a lot like java.util.Collection. */
public interface WhatEver {
private class Default implements Whatever {
// Methods...
}
/** A default implementation that is always empty. Suitable as a NULL value. */
public final WhatEver DEFAULT = new Default();
// Rest of interface...