Java接口方法:每个类应该实现一个接口吗?

时间:2010-04-17 17:41:29

标签: java interface

我一直在Java中为大学的一些课程编程,我有以下问题:

  

在方法上是否接受每个类都应该实现接口?不这样做被认为是不好的做法吗?你能描述一下使用接口不是一个好主意的情况吗?

编辑:就个人而言,我喜欢将接口用作一种方法和习惯的概念,即使它没有明显益处。 Eclipse自动创建了一个包含所有方法的类文件,因此它不会浪费任何时间。

13 个答案:

答案 0 :(得分:23)

如果您不打算使用它,则无需创建界面。

通常在以下情况下需要一个界面:

  • 您的程序将为您的组件提供多种实现。例如,作为代码一部分的默认实现,以及在JUnit测试中使用的模拟实现。有些工具可以自动创建模拟实现,例如EasyMock。
  • 您希望对此类使用依赖注入,使用Spring或JBoss Micro-Container等框架。在这种情况下,最好使用接口从一个类与其他类指定依赖关系。

答案 1 :(得分:18)

遵循YAGNI原则,如果确实需要,类应该实现接口。否则你从中获得了什么?

编辑:接口提供了一种抽象。如果要在不同的实现(实现相同接口的许多类)之间进行交换,它们特别有用。如果它只是一个类,那么就没有收获。

答案 2 :(得分:8)

每个类确实实现了一个接口(即契约),因为它提供了非私有API。是否应该选择将接口单独表示为Java接口取决于实现是否是“变化的概念”。

如果您完全确定只有一个合理的实现,那么就不需要接口。否则,接口将允许您在不更改客户端代码的情况下更改实现。

有些人会喊“YAGNI”,假设您可以在以后发现新要求时完全控制更改代码。其他人会害怕他们需要改变不可更改的 - 已发布的API。

如果你没有实现一个接口(并使用某种工厂来创建对象),那么某些类型的更改将迫使你打破开闭原则。在某些情况下,这是商业上可接受的,而在其他情况下则不是。

  

你能描述一下使用接口不是一个好主意的情况吗?

在某些语言(例如C ++,C#,但不是Java)中,如果您的类不包含虚拟方法,则可以获得性能优势。

在小程序或没有发布API的应用程序中,您可能会看到维护单独接口的成本很低。

如果由于分离接口和实现而导致复杂性显着增加,那么您可能不会将接口用作合同。接口降低了复杂性。从消费者的角度来看,组件成为履行合同条款的商品,而不是具有复杂实施细节的实体。

答案 3 :(得分:5)

不,每个类都没有必要实现接口。仅在使代码更清晰且更易于编写时才使用接口。

如果您的程序目前不需要为给定的类提供多于1个实现,那么您不需要接口。例如,在我写的一个简单的国际象棋程序中,我只需要一种类型的Board对象。棋盘是棋盘棋盘。制作一个Board接口并实现它只需要更多的代码来编写和维护。

如果您最终需要,可以轻松切换到界面。

答案 4 :(得分:4)

不需要为每个类创建接口。一些常见的原因包括模拟(不需要像Mockito这样的现代模拟框架)和依赖注入(例如Spring,现代实现中也不需要)。

如果需要,请创建一个接口,尤其是正式记录公共接口。有几个漂亮的边缘情况(例如标记接口)。

对于它的价值,在最近的一个项目中,我们使用了所有接口(DI和模拟被引用作为理由),结果证明它是完全浪费并增加了很多复杂性 - 它同样容易添加实际需要在极少数情况下模拟某些东西时的界面。最后,我确信有人会在某个周末进入并删除所有无关的接口。

我注意到C程序员首先转向Java倾向于喜欢大量的接口(“它就像标题”)。当前版本的Eclipse支持这一点,允许控件点击导航生成一个要求接口或实现的弹出窗口。

答案 5 :(得分:3)

我发现在相应的接口中定义类的公共方法是有益的,并且在定义对其他类的引用时严格使用接口引用。这允许容易地反转控制,并且还便于通过模拟和存根进行单元测试。它还为您提供了使用其他实现该接口的类替换实现的自由,因此如果您使用TDD,它可能会使事情变得更容易(或者如果您是TDD的批评者则更加做作)

答案 6 :(得分:2)

接口是获取多态性的方法。因此,如果您只有一个实现,一个特别类型的类,则不需要接口。

答案 7 :(得分:2)

以非常直率的方式回答OP的问题:不,并非所有类都需要实现接口。与所有设计问题一样,这归结为一个人的最佳判断。以下是我通常遵循的一些规则:

  • 可能是纯功能对象 不需要(例如,模式, CharMatcher - 即使是 后者确实实现了Predicate,它 是次要的核心功能)
  • 纯数据持有者可能不需要 到(例如LogRecord,Locale)
  • 如果您可以 设想一个不同的实现 给定功能(例如,内存中) 缓存与基于磁盘的缓存),尝试 将功能隔离到界面中。但也不要试图预测未来。
  • 出于测试目的,它是 这样做的课程非常方便 I / O或启动线程很容易模拟,所以 用户不支付罚款 正在进行测试。
  • 什么都没有 比泄漏它的界面更糟糕 底层实施。注意绘制线条的位置,并确保界面的Javadoc以这种方式保持中立。如果不是,您可能不需要界面。
  • 通常 说来,最好是 用于公共消费的课程 在你的包/项目之外 实现接口以便你的 用户与您的联系较少 执行du jour。

请注意,您可以找到该列表中每个项目符号的反例。接口非常强大,因此需要谨慎使用和创建它们,特别是如果您提供外部API(请this video说服自己)。如果你太快地将界面放在所有东西面前,你可能最终会泄漏你的单个实现,而你只会让跟随你的人变得更复杂。如果你没有充分使用它们,你最终可能会得到一个同样难以维护的代码库,因为一切都是静态绑定的,很难改变。上面的非详尽列表是我尝试画线的地方。

答案 8 :(得分:1)

学习被认为是好的方法的好方法,特别是在代码结构设计方面,是考虑免费提供的代码。使用Java,显而易见的例子是查看JDK system libraries

您将找到许多未实现任何接口的类的示例,或者可以直接使用的类,例如java.util.StringTokenizer。

答案 9 :(得分:1)

如果在应用程序界面中使用服务提供程序接口模式,则比抽象类更难扩展。如果向接口添加方法,则必须重写所有服务提供者。但是,如果向抽象类添加非抽象方法,则不得重写任何服务提供者。

如果只有一小部分接口方法通常具有有意义的实现,接口也会使编程更加困难。

答案 10 :(得分:0)

当我从头开始设计一个新系统时,我使用面向组件的方法,每个组件(10个或更多个类)提供一个接口,这允许我(有时)重用它们。

  • 在设计工具(或简单的系统)时,我认为这不一定是可扩展的框架,当我需要第二个实现作为选项时,我会引入接口。

  • 我看到一些产品通过界面暴露了几乎所有功能,只花了太多时间来理解不必要的复杂性。

答案 11 :(得分:0)

接口就像服务提供者(服务器)与此类服务(客户端)用户之间的合同。

  • 如果我们正在开发Web服务,我们正在公开其余路由 通过控制器类,控制器类可以实现接口 这些接口充当Web服务和Web服务之间的协议 其他使用此Web服务的应用程序。
  • Java接口,例如可序列化可克隆远程 用于向编译器或JVM指示内容。当JVM看到类时 实现这些接口,它对to执行一些操作 支持序列化,克隆或远程方法调用。如果您的类需要这些功能,那么您将必须实现这些接口。

答案 12 :(得分:-5)

使用Interface即将使您的应用程序框架能够适应变化。因为正如我在这里提到的那样(Multiple Inheritance Debates II: according to Stroustrup)我在java和c#中取消了多重继承,我应该总是使用Interface,因为你永远不知道将来会是什么。