我想了解在什么情况下应该使用泛型。
假设我想实现一个可迭代的LinkedList。显然,LinkedList应该具有通用的类型参数:
实施1:
public class LinkedList<E>{
private Node head;
private class Node{
private Node next;
private E e;
}
}
我的第一个问题:Node应该还有类型参数E吗?也就是说,如果上面的代码写成:
实施2:
public class LinkedList<E>{
private Node<E> head;
private class Node<E>{
private Node<E> next;
private E e;
}
}
两个实现都编译良好。我在我的教科书中看到了实施1。因此,似乎实现2有点不必要。
接下来,我想实现Iterable。假设我们坚持实施1,我们将:
实施3:
public class LinkedList<E> implements Iterable<E>{
private Node head;
private class Node{
private Node next;
private E e;
}
public Iterator<E> iterator(){
return new LinkedListIterator();
}
private class LinkedListIterator implements Iterator<E>{
private Node curr;
public boolean hasNext(){
return curr != null;
}
public E next(){
E element = curr.e;
curr = curr.next;
return element;
}
}
这是我在教科书中看到的标准实施方式。
我的第二个问题:既然我们没有Node的泛型类型,为什么我们也不能不使用泛型类型的Iterable和Iterator呢? e.g:
实施4:
public class LinkedList1<E> implements Iterable{
private Node head;
private class Node{
private Node next;
private E e;
}
public Iterator iterator(){
return new LinkedListIterator();
}
private class LinkedListIterator implements Iterator{
private Node curr = head;
public boolean hasNext(){
return curr != null;
}
public E next(){
E element = curr.e;
curr = curr.next;
return element;
}
}
}
答案 0 :(得分:2)
第一个问题:你是完全正确的,使用泛型为内部Node
类是不必要的。这是因为Node
是LinkedList<E>
的一部分,因此它已经是隐式通用的,不需要为此做更多的事情。如果Node
类是LinkedList
之外的单独类,则需要将其设为通用类。
编辑:要稍微深入一点,您的Node
类实际上属于LinkedList<E>
的每个实例。如果您有两个链接列表,则list1.Node
和list2.Node
不会被视为同一个类(就像list1.head
和list2,head
不是同一个变量)。无论list1
和list2
是否具有相同或不同的元素类型,都是如此。但这意味着Node
属于已经具有类型参数E
的对象,您也可以在E
内使用Node
(除非您重新声明它,其中如果您只能使用新声明的E
,它会掩盖E
中的LinkedList
。
如果您在LinkedList
中有静态声明,则上述内容不适用于它们。您已经知道所有实例都共享一个静态字段。如果您声明private static class Node …
,则该类将在所有链接列表之间共享。逻辑仍然有效,但您必须声明它是通用的(当您希望它是通用的;与LinkedList
之外的类相同)。此外,如果public static void main()
中有LinkedList
,因为它是静态的,即使是LinkedList
也不是通用的,并且如您在评论中所述,如果您从LinkedList
实例化Iterable
在这里,你应该给出一个类型参数。编辑结束。
第二个问题:正如您所发现的,您需要将类型参数传递给Iterator
和LinkedList
接口。这是因为它们不在您的LinkedListIterator
课程范围内,因此不属于您班级的通用范围。另一方面,您的LinkedList
非静态类位于LinkedList
内,因此是通用的,因为if (Gdx.input.isKeyJustPressed(Input.Keys.A))
player.position.x = player.position.x-moveSpeed;
本身并且不需要声明为通用。