问题描述
最近有人向我指出了这个问题(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,您已经创建了具有上一个和下一个节点的LinkedList,但是选择实现List接口中概述的方法?
猜猜我有点困惑,因为我认为LinkedList是一个实现List接口的类,但是对于test2,我们要创建一个LinkedList并再次实现List?
解决方法
LinkedList实现列表; 列表未实现LinkedList。
peek
是LinkedList
的一种方法,
但不是List
的方法。
由于这种情况,test2.peek()
是编译时错误。
具体来说, test2仅公开列表的功能。
,根据我的阅读,第一个LinkedList / List确定了哪些方法 可以使用。
是的,“第一个LinkedList / List”是您要声明的引用的类型。您可以在该引用上调用引用类型公开的方法,包括继承的方法,而不能包含其他方法。
因此对于test1,您可以执行test1.peek(),而对于 test2。
是的
是因为对于test2,您正在创建LinkedList 但是要实现List接口的方法吗?
不。 您在那里没有执行任何操作。您正在初始化引用test1
和test2
以引用 class LinkedList
的对象,该对象是implements
List
的具体类,因此提供了List
接口定义的所有方法的具体实现。 LinkedList
还提供了由其他接口和超类定义的某些方法的实现,原则上,它可以定义和实现一些其特有的方法。
在 换句话说,对于test2,您已经创建了一个具有上一个和下一个的LinkedList 节点,但选择实现列表中概述的方法 界面?
同样,您这里没有实现任何方法。通过选择通过类型为LinkedList<Integer>
的引用访问List<Integer>
对象,可以确保只能通过该引用调用LinkedList
定义的List
方法。这不会改变对象本身的性质。至少有时还会有其他引用,其中一些引用类型为LinkedList<Integer>
。那些可以用来调用对象上LinkedList
公开的方法,而List
不能公开。
猜我有点困惑,因为我认为LinkedList是一个 实现List接口,
是的
但是对于test2,我们正在创建一个 LinkedList并再次实现List?
每个LinkedList
都是一个List
。这是前一类implements
与后者的接口这一事实的主要后果之一。通过经由类型LinkedList
的引用访问类List
的对象,您将自己限制为仅使用List
定义的部分,但您并未更改对象本身以任何方式。仍然是LinkedList
。
考虑人类角色。我是一个儿子,一个兄弟,一个父亲,一个雇员,一个朋友以及许多其他事物,但是我一生中的大多数人仅根据其中一个或两个角色与我互动。例如,老板经常要求我(她的雇员)为她做各种工作,但她绝不会要求我像我父亲一样每周给她津贴。
类型,尤其是接口类型,可以看作是那些角色。如果您需要员工,则不必一定是完全像我一样的人,也可以是可以担任“雇员”角色的任何人。而且,扮演该角色并不能使任何人都不拥有其他所有角色。
,除了其他正确答案外,我还要指出编译器可以确保的内容:
LinkedList<Integer> test1 = new LinkedList<Integer>();
在这里,编译器将确保分配给test1
的任何内容都满足LinkedList
接口。
List<Integer> test2 = new LinkedList<Integer>();
在这里,编译器将确保分配给test2
的任何内容都满足List
接口'only'。
虽然这意味着您无法在LinkedList
上调用test2
接口的方法,但它可以灵活地将List
的任何实现分配给它,而无需更改它的任何用户。
这就是说:如果不需要特定的类型(接口),则应使用更通用的类型来保持灵活性。
因此,如果您只想知道元素的大小并进行迭代,则可以使用Collection
-但这将无法轻松访问第三个元素。