2016-04-25 126 views
3

我有一个类B它扩展了A存储AItem商店BItem泛型向数组中添加子类

在列表的列表 'A' 我有一个ArrayList的其使用[?扩展了AItem]。

我认为这意味着我可以使用此ArrayList的任何类型的扩展AItem的对象。

所以在我的B类中,我有一个方法add(..),它将BItem添加到项目中。

我认为这将工作,因为项目arrayList可以容纳从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{} 

我该如何得到这个工作?

我的编译错误是这样的:

Add方法(捕获#2的扩展AItem?)在类型 ArrayList中是不适用的 参数(BItem)

+0

无法项目添加到[我如何添加 – Ian2thedv

+1

未知类型可能重复的名单到列表<?扩展数字>数据结构?](http://stackoverflow.com/questions/2776975/how-can-i-add-to-list-extends-number-data-structures) – Ian2thedv

+0

非常好的问题。我保持寻找答案,但我认为你需要用一些类来初始化arrayList。 – jabujavi

回答

6

你可能不需要在这里使用泛型。具有AAItem类型的列表应该罚款(我也将宣布它List代替ArrayList类型的最佳实践):

class A { 
    public List<AItem> items; 
} 

class B extends A { 

    public void add(BItem i) { 

     this.items.add(i); 
    } 
} 

? extends AItem的问题是,编译器不能保证实际类型的元素是AItemBItem。它可能是另一个子类CItem,在这种情况下类型安全性被破坏。

另外的方法来设计类层次结构与仿制药,在其中设置的类型参数在父类中,并将其设置在扩展类B适当的子类(BItem):

class A<T extends AItem> { 
    public ArrayList<T> items; 
} 

class B extends A<BItem>{ 

    public void add(BItem i) { 

     this.items.add(i); 
    } 
} 
+0

我不认为我可以简化,就像你的第一个答案。让我回到你身边.. –

2

尝试用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{} 

更换extends您可能会发现有关原因的更多细节behin d这种行为,here

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); 
    } 
}