当我使用实现ArrayList
的类并更改元素的泛型类型时,我注意到有趣的Java(或至少是Netbeans)。我基本上创建了一个扩展ArrayList
的抽象类和一些应该与String
对象一起使用的子类(类似于ArrayList<String>
)。我努力实现的目标之一是:
public abstract class A extends ArrayList {
...
}
@Override
public abstract class B extends A {
public Iterator<String> iterator() {
return super.iterator();
}
}
另一个是:
public abstract class A extends ArrayList {
...
}
public abstract class B<String> extends A {
@Override
public Iterator<String> iterator() {
return super.iterator();
}
}
第一个成功覆盖iterator()
方法,为其分配String值。另一个以某种方式取消了类型转换。有趣的是,当涉及到循环时,它们都不起作用。这会收到Object
类型,而不是String
。
for (String s : B) {
...
}
你知道为什么会发生这种情况吗?如何在不实现我自己的迭代器的情况下修复它?
答案 0 :(得分:4)
不确定你要做什么,但如果我理解正确你想要一个扩展ArrayList的类并且有一个Generic类型的String ...也许你正在寻找这个:
public abstract class A<T> extends ArrayList<T> {
...
}
public abstract class B extends A<String> {
...
}
然后在你的代码中,这个:
B myList = ...;
for ( String s : myList ) {
...
}
工作得很好。虽然我认为你可以提出一个更好的解决方案。你有关于你的问题的更多细节吗?
答案 1 :(得分:1)
使用合成而不是继承
public class A implements Iterable<String>{
List<String> myList = new ArrayList<String>();
//do operations on myList
public Iterator<String> iterator() {
return myList.iterator();
}
}
答案 2 :(得分:0)
如果你扩展泛型类,你应该关心泛型。我的意思是你的声明应该是
public abstract class A extends ArrayList<String> {
...
}
如果你想使用字符串或
public abstract class <T> A extends ArrayList<T> {
...
}
如果你希望你的班级是通用的。
在这两种情况下,您不必重写iterator()
方法:您可以从超类调用它,它将返回“好”迭代器。您的声明等同于
public abstract class A extends ArrayList<Object> {
...
}
这就是“奇怪”行为的原因。
我可以问你为什么要延长ArrayList
?这听起来很奇怪。
答案 3 :(得分:0)
public abstract class B<String> extends A {
@Override
public Iterator<String> iterator() {
return super.iterator();
}
}
String
不是类String
,而是声明一个名为String
的新类型变量(如T
),它隐藏了类String