在Java程序编写中常用接口作为一个变量声明的类型,比如下面一行代码声明一个数组,使用了接口Collection来声明:
Collection<String> c = new ArrayList<String>();
在 Java 中,声明一个 ArrayList
对象并赋值给 Collection
接口类型的变量是完全可以的,因为 ArrayList
是 Collection
接口的一个具体实现。
这样做有几个原因:
-
多态性:Java 中的多态性允许我们将一个子类的引用赋值给一个父类类型的变量。在这里,
ArrayList
是Collection
接口的一个子类(实现),所以我们可以将ArrayList
的引用赋值给Collection
类型的变量。 -
抽象和灵活性:使用接口作为引用类型可以增加代码的抽象性和灵活性。这样做意味着我们可以将
c
引用指向任何实现了Collection
接口的对象,而不仅仅是ArrayList
。例如,以后如果需要改变实现,从ArrayList
改为LinkedList
或其他任何实现了Collection
接口的类,只需要改变创建实例的那一行代码,而不需要修改引用c
的其他代码。 -
类型安全:使用泛型(如
Collection<String>
)可以确保集合中只能包含特定类型的对象(在这个例子中是String
类型)。这样,在运行时就可以避免插入错误类型的对象。 -
减少依赖:将代码设计为依赖于接口而不是具体实现,可以使得代码更加解耦,更容易测试和维护。
虽然使用 ArrayList
的具体类型也是完全可以的,但使用接口作为引用类型通常是一个更好的做法,因为它提供了更大的灵活性和抽象性。当然,在某些情况下,如果需要访问 ArrayList
的特定方法(例如 ensureCapacity
或 trimToSize
),这时就要声明变量为 ArrayList
类型。但在大多数情况下,使用接口作为类型是一个更好的选择。