【问题标题】:Isn't it easier to work with foo when it is represented by the class ArrayList rather than the interface List?当 foo 由类 ArrayList 而不是接口 List 表示时,使用 foo 不是更容易吗?
【发布时间】:2011-04-02 09:10:32
【问题描述】:

我经常看到这种语法,但不明白其背后的原因。我认为您通常希望使用类而不是接口,以便更轻松地执行您可能想要执行的全部操作。

为什么这样做:

List<Foo> foo = new ArrayList<Foo>(something.getFoo());

而不是这个:

ArrayList<Foo> foo = new ArrayList<Foo>(something.getFoo());

当你以后想对 foo 执行操作时?如果 foo 由类 ArrayList 而不是接口 List 来表示,不是更容易吗?

【问题讨论】:

  • 感谢您向我介绍panoply这个词:)
  • 我曾经使用过的唯一对ArrayList 特殊的方法是removeRange。对于日常使用,List 是字段/变量类型的最佳选择。

标签: java generics oop class interface


【解决方案1】:

偶尔,是的。如果您实际上需要一个在ArrayList&lt;T&gt; 中声明但不在List&lt;T&gt; 中声明的方法,那么当然,去吧。

然而,反过来更灵活 - 如果您不需要需要在 ArrayList&lt;T&gt; 中声明的任何方法,那么您的代码可以通过将变量声明为 List&lt;T&gt; 类型来表达这一点.也就是说,“我只需要一个列表。我碰巧选择了ArrayList&lt;T&gt;,但这只是因为它的行为适合我……而不是因为我需要它公开的任何额外功能。”

例如,如果以后有人想知道他们是否可以替换不同的实现,这很有用。它还限制了读者必须思考的程度……变量的类型越通用,使用它的人就越少 - 所以需要思考的人就越少。

例如,如果我看到一个Iterable&lt;T&gt; 类型的变量,我知道以后可能会用它来处理它:基本上,它将用于迭代,仅此而已。我不需要担心以后的代码是否会尝试向集合添加值,或者通过索引等访问它。

这对于局部变量相对并不重要,但对于实例变量尤其是参数来说更重要:参数越不具体,调用者在传递哪些参数时就越灵活.

【讨论】:

    【解决方案2】:

    为了使您的代码保持良好的解耦,最好隐藏实现细节,以便您以后可以以不同的方式做事。

    因此,习惯上只公开其他部分需要的接口,以避免其他人对你以后必须履行的合同做出假设。

    如果大量使用特定实现,当您从方法 A 获取 LinkedList 并从方法 B 获取 ArrayList 时,您最终会得到扭曲的代码。

    针对接口进行编程还可以更轻松地在单元测试中模拟对象。

    【讨论】:

      【解决方案3】:

      多态性的全部意义在于将您的实现绑定到另一个数据类型的实现。在这种情况下,您不想将您的类与 ArrayList 结合起来。相反,您希望将您的类与抽象 List 类型结合起来。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-05
        • 2015-08-28
        • 2020-10-03
        • 1970-01-01
        • 2017-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多