我非常高兴地说,我刚刚在几周前的一个项目中实现了通用链表,并且它有效!不过,有一个问题。我被迫做一个演员(没想到(。
这里有一些片段,我希望足以定义问题,从通用堆栈开始:
public class GenericStack<E> {
public LinkedList <E> stack = new LinkedList<>();
public void push (E obj){
stack.add(obj);
}
public E pop() {
if (stack.isEmpty()) return null;
return stack.removeLast();
}
...
}
这是我使用泛型堆栈的类定义:
public class Grid extends GenericStack<JTextField> implements ActionListener, KeyListener, KeyCodes
这是我定义stack
以及我正在推动和弹出的内容:
GenericStack stack = new GenericStack();
public static JTextField[][] cells = new JTextField[11][11];
这是我推到stack
:
stack.push(Grid.cells[currentCell.row][currentCell.col]);
这是我从stack,
弹出的地方,只有当我做所示的演员表时才有效:
private void calculate(){
JTextField w = new JTextField();
while(stack.size()>0){
w = (JTextField) stack.pop();
System.out.println("stack element " + w.getText());
}
}
现在我不是在抱怨;我什至不确定是否有问题要处理,但是如果没有演员(JTextField)
,我得到">不兼容的类型--必需:JTextField;FOUND: Object",但stack.pop()
明确定义为返回泛型类型,即JTextField
,那么为什么我需要强制转换呢?
这是问题所在:
GenericStack stack = new GenericStack();
那是使用原始类型的GenericStack
。老实说,当你已经扩展了GenericStack<JTextField>
时,你根本不清楚为什么会有这个。我希望你要么使用构图:
public class Grid implements ActionListener, KeyListener, KeyCodes {
private final GenericStack<JTextField> stack = new GenericStack<JTextField>();
private void calculate() {
while (stack.size() > 0) {
JTextField w = stack.pop();
System.out.println("stack element " + w.getText());
}
}
}
或使用继承:
public class Grid extends GenericStack<JTextField>
implements ActionListener, KeyListener, KeyCodes {
private void calculate() {
while (size() > 0) {
JTextField w = pop();
System.out.println("stack element " + w.getText());
}
}
}
目前你把两者混在一起,这真的很奇怪。
在以下实例化中使用了泛型类型的原始类型:
GenericStack stack = new GenericStack();
使用原始类型时,类中的所有泛型类型都将替换为其原始类型对应项,类型参数将替换为其擦除。由于在您的情况下删除E
是Object
,因为它没有任何界限。因此,链表和方法:
public LinkedList <E> stack = new LinkedList<>();
public void push (E obj) { ... }
public E pop() { ... }
将被擦除为:
public LinkedList stack = new LinkedList();
public void push(Object obj) { ... }
public Object pop() { ... }
因此,当您调用pop()
方法时,您会返回Object
类型。
你需要的是一个参数化的实例化:
GenericStack<JTextField> stack = new GenericStack<>();
当然,JonSkeet在他的回答中说的。不要混淆继承和组合。您有一个类型 GenericStack
的引用,并且还对其进行了扩展。这没有意义。遵循乔恩回答中的建议。
D'OH!!
很高兴它工作了,我忽略了一些明显的(对有经验的人(的事情(我真的没有理由忽视(,所以是的,我做了罗希特·贾恩建议的更改(在注意到乔恩·斯基特(Jon Skeet(的相同之后(,我有一个更时尚的弹出方法:
private void calculate(){
while(stack.size()>0){
System.out.println("stack element " + stack.pop().getText());
}
}
(方法被称为calculate
,因为它很快就会这样做。
但是,Jon,我不明白我的代码如何表明我正在混合组合和继承,但也许这是因为我刚才也不完全理解!
不过,我会告诉你这一点:每天(一整天??(的挫败感只是为了让多一行代码工作已经结束。Java摇滚!(一旦你到达学习曲线上的某个点!(我对我在短短几天内在这方面走了多远感到震惊!(好吧,也许咖啡有帮助!