简体   繁体   English

泛型将子类添加到数组中

[英]Generics adding subclasses to array

I have a class B which extends A . 我有一个扩展A的 B级。 A stores a list of AItem and B stores a list of BItem A存储AItemBBItem名单列表

In 'A' I have an ArrayList which uses [ ? 在“A”我有一个使用[一个ArrayList? extends AItem ] . 扩展AItem ]。

I assume this means that I can use this ArrayList for objects of any type that extends AItem. 我认为这意味着我可以将此ArrayList用于任何扩展AItem的类型的对象。

So in my B class I have a method add(..) which adds a BItem to the items. 所以在我的B类中,我有一个方法add(..),它为项添加了一个BItem。

I assumed this would work because the items arrayList can hold a list of any object that extends from AItem. 我认为这样可行,因为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{}

How would I get this to work? 我怎么能让这个工作?

My compile error looks like this : 我的编译错误如下所示:

The method add(capture#2-of ? extends AItem) in the type ArrayList is not applicable for the arguments (BItem) 方法add(捕获#2-of?extends AItem)在ArrayList类型中不适用于参数(BItem)

You probably don't need to use generics here. 您可能不需要在这里使用泛型。 Having the list of type AItem in class A should be fine (I would also declare it of type List instead of ArrayList for best practices): 在类A中具有类型AItem的列表应该没问题(我还将声明它的类型为List而不是ArrayList以获得最佳实践):

class A {
    public List<AItem> items;
}

class B extends A {

    public void add(BItem i) {

        this.items.add(i);
    } 
}

The problem with ? extends AItem 这个问题? extends AItem ? extends AItem is that the compiler cannot guarantee that the actual type of the elements is AItem or BItem . ? extends AItem是编译器不能保证元素的实际类型是AItemBItem It could be another subclass CItem in which case the type safety is broken. 它可能是另一个子类CItem在这种情况下,类型安全性被打破。

There is another approach to designing the class hierarchy with generics, in which you set the type parameter in the parent class and set it to the appropriate subclass ( BItem ) in the extended class B : 还有另一种方法来设计类层次结构与仿制药,在其中设置的类型参数在父类中,并将其设置到适当的子类( 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);
    } 
}

Try replacing extends with super 尝试用super替换extends

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{}

You may find more details about the reason behind this behavior, here 您可以在此处找到有关此行为背后原因的更多详细信息

you can use 您可以使用

public ArrayList<? super AItem> items; 

and you can add to the list now 你现在可以添加到列表中

but you will not be able to do 但你将无法做到

public class B extends A{
 .....

   public BItem getOne(int idx) {
     return this.items.get(idx);

   }
}

jvm doesn't know what will be actually in the list. jvm不知道列表中的实际内容。

you can generify the A class 你可以通过A类来生成

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

then define your B class as 然后将您的B类定义为

public class B extends A<BItem>{

    public void add(BItem i) {

        this.items.add(i); 
    } 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM