Java中的接口优势

我的问题很简单:如果它们是由单个类实现的,那么使用接口是否有任何优势?
我一直认为只有当该接口有多个实现时,接口才是好的。

谢谢。

总之一句:不。 接口的合同可以直接在您的类中指定。

如果您明确表示将来不需要再使用相同方法,则可以避免定义接口。

当然,这里的问题是“未来”条款。 如果项目很小,没有很长的开发/升级期,并且定义明确,那么您几乎可以确定将来需要什么。

如果项目很长,可能会有变化,那么你将不得不考虑:

  • 你最终需要一个接口的概率。
  • 你现在知道接口将来需要什么方法的概率。
  • 现在做界面的成本与未来的重构有关。

考虑到现在可能只有一个实现,但将来可能会出现更多的实现。 此外,通过使用接口,您可以通过仅使用接口来避免创建对具体类的依赖性。 然后,稍后,如果您决定更改实现,则可以创建一个实现接口的新实现,而不会对仅依赖于您的接口的其他代码产生不利影响。

考虑:

public interface SomeInterface {...} public class AConsumerOfSomeInterface { private SomeInterface service; public AConsumerOfSomeInterface(SomeInterface theImplementation) { service = theImplementation; } //some code which uses the service } 

现在,您可以在未来更改此类的情况下交换实现。 因为这很容易做到,即使您认为不需要接口也很有意义。

接口是一种解耦单独软件组件的方法。 当然,您今天可以使用Oracle数据库存储所有数据,为什么不分配所有DAO接口?

答案是强烈耦合到任何东西可能会回来并在将来咬你。 如果明年你想使用一些云服务存储数据怎么办? 如果你编码为DAO接口,你可以简单地引入一个新的云实现并直接插入。你的应用程序松散耦合,所以不需要改变。

我想补充一点:接口有助于代理模式 。

在Web应用程序中,此代理对抽象有很大帮助。 我是Web应用程序的新手,但通常我通过接口设计我的服务层。 在使用Wicket构建的Web应用程序中,我有一个接口Afrodite和一个AfroditeImpl类作为服务层,从applicationContext初始化为spring bean。 然后我们可以获得Afrodite定义的所有方法,并通过所有网页在Afrodite实现

 AfroditeApplication application = (AfroditeApplication)getApplication(); Afrodite afrodite = application.getAfrodite(); // Now call the service layer's methods by afrodite 

大纲是:

 public interface Afrodite { } public class AfroditeImpl implements Afrodite { } public class AfroditeApplication extends WebApplication { Afrodite afrodite; public Afrodite getAfrodite() { return afrodite; } @Override public void init() { super.init(); ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); afrodite = (Afrodite) applicationContext.getBean("afrodite"); } } 

希望这可以帮助。

问问自己是否真的有可能在不久的将来有多个实施。

您可以在需要时轻松添加界面,有时还可以添加多个界面。

我为单个类创建接口的唯一情况是区分常用的API和专用API (测试,监控等)。

如果它们是由单个类实现的,那么使用接口是否有任何优势?

如果你的界面只由一个类实现,并且你100%确定你永远不会觉得需要添加另一个实现,那么没有任何优势。

无论如何,我认为还有另一种情况需要牢记。 假设您有一个类比您想要向另一个客户端类公开的更多。 可以使用接口来限制客户端可以调用的类的方法:

 public interface clientInterface{ public foo(); public bar(); } public class yourClass implements clientInterface{ public foo(){} public bar(){} public doSomethingElse(){} } public class clientSideFactory{ public clientInterface getClass(){ return new yourClass(); } } public class internalSideFactory{ public clientClass getClass(){ return new yourClass(); } } } 

在上面说明的情况中,即使您有一个接口clientInterface的单个实现(clientClass),这也很有用,可以返回到只能看到类的有限部分的客户端类(限制类完整实现的可见性) )。