【问题标题】:Why on assignment declaration declare an interface on the left and an implementing class on the right? [duplicate]为什么在赋值声明时在左边声明一个接口,在右边声明一个实现类? [复制]
【发布时间】:2013-08-01 22:48:07
【问题描述】:

我在 Java 和 C# 代码中经常注意到这种模式,因此出于某种原因我认为这是一种“最佳实践”,但我不确定为什么。因此,例如在 Java 中我可能会看到...

List<String> list = new ArrayList<String>();

这仅在一个地方声明(显然),并且仅适用于一个代码块,有什么意义?为什么不说...

ArrayList<String> list = new ArrayList<String>();

...?

【问题讨论】:

  • 有很多重复
  • 一个流行的原因是您可以在不破坏代码的情况下更改类型(更改为另一个实现该接口的类型)。
  • 另一个(仅限 .NET):IEnumerable&lt;T&gt; 无法修改集合,因为添加、删除或清除方法来自子接口 ICollection&lt;T&gt;。因此,如果您希望它是不可变的,请使用基本接口。

标签: c# java oop inheritance interface


【解决方案1】:

是的,这是最佳做法。 因为稍后在您的代码中,您可以使用 LinkedList&lt;String&gt;CustomListImpl&lt;String&gt; 更改实现,而无需更改客户端代码

假设您使用了一些具有方法的第三方库:

ArrayList<Document> getAllDocuments(){...}

在这种情况下,如果库作者将ArrayList 更改为LinkedList,它将破坏您的所有代码(您将有编译错误);

ArrayList<Document> list = getAllDocuments()//compilation error here

如果库方法将使用接口声明

List<Document> getAllDocuments(){...}

作者会将实现更改为LinkedList,您的代码将可以正常工作,例如:

List<Document> list = getAllDocuments()//you do not worry here about implementation

所以使用Interfaces 允许您在抽象级别而不是实现级别

创建程序

【讨论】:

    【解决方案2】:

    因为List&lt;String&gt; 声明了一个对象,该对象能够响应List 接口可用的所有方法。 ArrayList 可能有更多方法可用于该特定实现。

    声明

    ArrayList<String> list = new ArrayList<String>();
    

    将允许您使用任何特定于ArrayList 的方法。但是,让我们想想有一天您会意识到ArrayList 并不是解决您的问题的最佳方法。如果你有

    List<String> list = new ArrayList<String>();
    

    那你可以直接改成

    List<String> list = new LinkedList<String>();
    

    保证不会破坏代码中的任何其他内容,因为 list 仅用作 List&lt;String&gt;,因此您没有在其上使用任何额外功能。

    一般而言,您对特定类型的假设越少越好。这是因为您只是通过接口与类型交互,因此您并不关心确切的类型是什么或它具有什么额外功能,您只关心接口提供的方法。当然,这并不总是可行的,因为有时您需要使用该特定功能。

    【讨论】:

    • 我意识到我的问题是重复的,但很好的答案,谢谢。
    猜你喜欢
    • 2013-07-06
    • 2015-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多