我有一个 B 类,它扩展了 A 。 A 存储 AItem 列表, B 列出 BItem
列表在' A'我有 ArrayList ,它使用[?扩展AItem ]。
我认为这意味着我可以将此ArrayList用于任何扩展AItem的类型的对象。
所以在我的B类中,我有一个方法add(..),它为项添加了一个BItem。
我认为这样可行,因为itemsList可以保存从AItem扩展的任何对象的列表。
import java.util.ArrayList;
class A {
public ArrayList<? extends AItem> items;
}
public class B extends A{
public void add(BItem i) {
this.items.add(i); //compile error here
}
}
//items :
class AItem {}
class BItem extends AItem{}
我怎样才能让它发挥作用?
我的编译错误如下所示:
该方法在类型中添加(捕获#2-of?extends AItem) ArrayList不适用于 参数(BItem)
答案 0 :(得分:6)
您可能不需要在这里使用泛型。在类AItem
中使用A
类型的列表应该没问题(我还会声明类型List
而不是ArrayList
以获得最佳做法):
class A {
public List<AItem> items;
}
class B extends A {
public void add(BItem i) {
this.items.add(i);
}
}
? extends AItem
的问题在于编译器无法保证元素的实际类型为AItem
或BItem
。它可能是另一个子类CItem
,在这种情况下,类型安全性会被破坏。
是另一种使用泛型设计类层次结构的方法,您可以在其中设置父类中的type参数并将其设置为扩展中的相应子类(BItem
)班B
:
class A<T extends AItem> {
public ArrayList<T> items;
}
class B extends A<BItem>{
public void add(BItem i) {
this.items.add(i);
}
}
答案 1 :(得分:2)
尝试将extends
替换为super
import java.util.ArrayList;
class A {
public ArrayList<? super AItem> items;
}
public class B extends A{
public void add(BItem i) {
this.items.add(i); //compile error here
}
}
//items :
class AItem {}
class BItem extends AItem{}
您可以找到有关此行为背后原因的更多详细信息,here
答案 2 :(得分:1)
你可以使用
public ArrayList<? super AItem> items;
您可以立即添加到列表中
但你将无法做到
public class B extends A{
.....
public BItem getOne(int idx) {
return this.items.get(idx);
}
}
jvm不知道列表中的实际内容。
你可以生成A类
class A<T> {
public ArrayList<T> items;
}
然后将您的B类定义为
public class B extends A<BItem>{
public void add(BItem i) {
this.items.add(i);
}
}