Interface programming for LinkedLists 链表的接口编程

huangapple go评论60阅读模式
英文:

Interface programming for LinkedLists

问题

I was recently pointed to this question (https://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an interface) and wanted to get some clarification.

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

From what I've read, the first LinkedList/List determines what methods can be used. 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? 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?

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?

英文:

I was recently pointed to this question (https://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface) and wanted to get some clarification.

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

From what I've read, the first LinkedList/List determines what methods can be used. 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? 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?

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?

答案1

得分: 1

LinkedList实现了List;
List不实现LinkedList。

peekLinkedList的一个方法,
但不是List的方法。

因为这种情况,test2.peek()是一个编译时错误。

具体来说,
test2只暴露了List的功能。

英文:

LinkedList implements List;
List does not implement LinkedList.

peek is a method of a LinkedList,
but is not a method of List.

Because of this situation, test2.peek() is a compile time error.

Specifically,
test2 only exposes the functionality of a List.

答案2

得分: 1

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

是的。

这是因为对于test2,您正在创建一个LinkedList,但将要实现List接口的方法吗?

不是的。在这里,您不是在实现任何东西。您正在初始化引用test1和test2以引用LinkedList类的对象,它是一个具体类,实现了List接口,并因此提供了List接口定义的所有方法的具体实现。LinkedList还提供了一些由其他接口和超类定义的方法的实现,并且原则上它可以定义和实现一些唯一属于它的方法。

换句话说,对于test2,您创建了一个具有prev和next节点的LinkedList,但选择实现List接口中列出的方法吗?

再次强调,在这里您不是在实现任何方法。通过选择通过List<Integer>类型的引用访问LinkedList<Integer>对象,您确保只能通过该引用调用由List定义的那些LinkedList方法。这不会改变对象本身的性质。至少有时会有其他引用指向它,其中一些类型为LinkedList<Integer>。这些引用可以用来调用由LinkedList而不是List公开的方法。

我猜我有点困惑,因为我以为LinkedList是实现了List接口的类,

是的。

但是对于test2,我们正在创建一个LinkedList并再次实现List接口吗?

每个LinkedList都是List。这是前者类实现后者接口的主要后果之一。通过通过List类型的引用访问LinkedList类的对象,您仅限于使用由List定义的部分内容,但您没有以任何方式更改对象本身。它仍然是一个LinkedList。

考虑人类的角色。我是一个儿子,一个兄弟,一个父亲,一个雇员,一个朋友,还有很多其他角色,但我的生活中大多数人只根据其中一个或两个角色与我互动。例如,我的老板经常要求我,她的雇员,为她做各种工作,但她永远不会要求我像是她的父亲一样给她每周零用钱。

类型,特别是接口类型,可以像那些角色一样看待。如果您需要一名员工,它不必是我这样的人 - 它可以是任何可以扮演“员工”角色的人。并且在该角色中的操作不会使任何人失去他们所有其他的角色。

英文:

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

Yes, the "first LinkedList/List" is the type of the reference you are declaring. You can invoke the methods exposed by a reference's type on that reference, including inherited ones, and no others.

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

Yes.

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

No. You are not implementing anything there. You are initializing references test1 and test2 to refer to objects of class LinkedList, which is a concrete class that implements List, and therefore provides concrete implementations of all methods defined by the List interface. LinkedList also provides implementations of some methods defined by other interfaces and by superclasses, and, in principle, it could define and implement some methods unique to it.

> 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?

Again, you are not implementing any methods here. By choosing to access a LinkedList&lt;Integer&gt; object via a reference of type List&lt;Integer&gt;, you ensure that only those LinkedList methods that are defined by List can be invoked via that reference. That doesn't change the nature of the object itself. There will be other references to it at least sometimes, some of them of type LinkedList&lt;Integer&gt;. Those can be used to invoke methods exposed by LinkedList but not by List on the object.

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

Yes.

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

Every LinkedList is a List. This is one of the main consequences of the fact that former class implements the latter interface. By accessing an object of class LinkedList via a reference of type List, you limit yourself to using only those parts of it that are defined by List, but you have not changed the object itself in any way. It is still a LinkedList.

Consider human roles. I'm a son, a brother, a father, an employee, a friend, and many other things, but most people in my life interact with me according to only one or two of those roles. For example, my boss regularly asks me, her employee, to do various pieces of work for her, but she would never ask me to give her a weekly allowance as if I were her father.

Types, and in particular interface types, can be regarded like those roles. If you need an employee, it doesn't have to be someone exactly like me -- it can be anyone who can fill the "employee" role. And operating in that role does not make anyone not have all their other roles.

答案3

得分: 0

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

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

在这里,编译器会确保任何分配给test1的内容都符合LinkedList接口。

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

在这里,编译器会确保任何分配给test2的内容仅符合List接口。

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

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

英文:

In addition to the other correct answers, I'd like to point out what the compiler ensures:

LinkedList&lt;Integer&gt; test1 = new LinkedList&lt;Integer&gt;(); 

Here the compiler will make sure that anyting assigned to test1 fulfills the LinkedList interface.

List&lt;Integer&gt; test2 = new LinkedList&lt;Integer&gt;(); 

Here the compiler will make sure that anyting assigned to test2 fulfills the List interface 'only'.

While that means you cannot call methods of the LinkedList interface on test2, it gives the flexibility to assign any implementation of List to it without changing any user of it.

That said: if you do not need specific types (interfaces), you should use a more common type instead to stay more flexible.
So if you only want to know the size and iterate the elements, you could use Collection - but this will not allow to access the 3rd element easily.

huangapple
  • 本文由 发表于 2020年8月13日 05:11:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/63384775.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定