链表的接口编程

Interface programming for LinkedLists

最近有人向我提出了这个问题 (What does it mean to "program to an interface"?),我想得到一些说明。

LinkedList<Integer> test1 = new LinkedList<Integer>(); 
List<Integer> test2 = new LinkedList<Integer>(); 

根据我的阅读,第一个 LinkedList/List 决定了可以使用的方法。因此,对于 test1,您可以执行 test1.peek() 而对于 test2 则不能。那是因为对于 test2,您正在创建一个 LinkedList 但要实现 List 接口的方法吗?换句话说,对于 test2,您已经创建了一个带有 prev 和 next 节点的 LinkedList,但选择实现 List 接口中概述的方法?

猜猜我有点困惑,因为我认为 LinkedList 是一个 class 实现了 List 接口,但是对于 test2,我们创建一个 LinkedList 并再次实现一个 List?

LinkedList实现List; List 没有实现 LinkedList。

peek是一个LinkedList的方法, 但不是 List.

的方法

由于这种情况,test2.peek()是编译时错误。

具体来说, test2 仅公开了 List 的功能。

From what I've read, the first LinkedList/List determines what methods can be used.

是的,“第一个 LinkedList/List”是您声明的引用类型。您可以在该引用上调用引用类型公开的方法,包括继承的方法,但不能调用其他方法。

So for test1, you can do test1.peek() while you can't for test2.

是的。

Is that because, for test2, that you are creating a LinkedList but going to be implementing the methods of the List interface?

没有。 没有在那里实现任何东西。您正在初始化引用 test1test2 以引用 class LinkedList 的对象,这是一个具体的 class implements List,因此提供了 List 接口定义的所有方法的具体实现。 LinkedList也提供了其他接口和superclasses定义的一些方法的实现,原则上,它可以定义和实现一些它独有的方法。

In other words, for test2, you've created a LinkedList with a prev & next node but are choosing to implement the methods outlined in the List interface?

同样,您没有在此处实现任何方法。通过选择通过 List<Integer> 类型的引用访问 LinkedList<Integer> 对象,您可以确保只有 List 定义的那些 LinkedList 方法可以通过该引用调用。这不会改变对象本身的性质。至少有时会有其他引用,其中一些类型为 LinkedList<Integer>。这些可用于调用对象上 LinkedList 而不是 List 公开的方法。

Guess I'm a bit confused because I thought LinkedList is a class that implements the List interface,

是的。

but for test2, we're creating a LinkedList and implementing a List again?

每个LinkedList一个List。这是前者 class implements 后者接口这一事实的主要后果之一。通过 List 类型的引用访问 class LinkedList 的对象,您限制自己只能使用由 List 定义的那些部分,但您没有以任何方式改变对象本身。依旧是LinkedList.

考虑人类的角色。我是儿子、兄弟、父亲、雇员、朋友和许多其他角色,但我生活中的大多数人只根据其中一两个角色与我互动。例如,我的老板经常要求我,她的员工,为她做各种工作,但她绝不会要求我给她每周的津贴,就像我是她的父亲一样。

类型,尤其是接口类型,可以看作是那些角色。如果您需要一名雇员,不必是完全像我这样的人——可以是任何可以担任“雇员”角色的人。担任该角色并不意味着任何人都没有其他角色。

除了其他正确答案外,我想指出编译器确保的内容:

LinkedList<Integer> test1 = new LinkedList<Integer>(); 

此处编译器将确保分配给 test1 的任何内容满足 LinkedList 接口。

List<Integer> test2 = new LinkedList<Integer>(); 

此处编译器将确保分配给 test2 的任何内容满足 List 接口 'only'.

虽然这意味着您不能在 test2 上调用 LinkedList 接口的方法,但它可以灵活地将 List 的任何实现分配给它而无需更改它的任何用户。

就是说:如果您不需要特定的类型(接口),您应该使用更通用的类型来保持灵活性。 因此,如果您只想知道大小并迭代元素,则可以使用 Collection - 但这将不允许轻松访问第三个元素。