将ArrayList <subclass>转换为ArrayList <superclass> </superclass> </subclass>

时间:2014-04-21 14:56:36

标签: java

我有三个类:Blob,Food和Predator,所有这些都是抽象类Organism的子类。

我还为每个类都有一个ArrayList:blob,食物和捕食者

我正在编写一个能够选择“目标”的功能。对于有机体,取决于它的类型。有机体作为参数传递,然后选择适当的目标 - 如果Blob通过则它应该以食物为目标,如果通过Predator然后它应该以Blob为目标,如果食物通过那么它应该以捕食者。现在我有:

ArrayList<Food> foods = new ArrayList<Food>();
ArrayList<Blob> blobs = new ArrayList<Blob>();
ArrayList<Predator> predators = new ArrayList<Predator>();

public Organism pickTarget(Organism o){
    ArrayList<Organism> search = new ArrayList<Organism>();
    if(o.getClass() == Blob.class){
        search = foods;
    }
    else if(o.getClass() == Predator.class){
        search = blobs;
    }
    else if(o.getClass() == Food.class){
        search = predators;
    }

    Organism target = search.get(0);
    for(Organism organism:search){
        //do stuff to pick a target from assigned search space
    }

    return target;
}

因此,这里的想法是初始化一个通用的Organisms ArrayList,然后根据参数的类型为其分配一个现有的ArrayLists。然后将搜索该ArrayList以寻找最合适的返回目标。

但是当我尝试将现有的ArrayList分配给搜索变量时,我收到了类型不匹配错误。 &#39;无法从ArrayList<Food>转换为ArrayList<Organism>&#39;,例如。

有人知道像这样的问题的解决方案吗?从子类转换为超类通常不是问题所以我希望有一个ArrayLists的解决方案。

2 个答案:

答案 0 :(得分:6)

您面临的根本问题是List<Subclass> List<Superclass>的子类型。

解决问题的方法是使用通用绑定声明变量:

List<? extends Organism> search;

然后这将编译:

search = foods;

声明List<? extends Organism>表示&#34;未知类型的列表,它是生物体的子类型&#34;。在代码中,这样一个列表的元素至少是一个有机体,但确切的类型是未知的。

答案 1 :(得分:0)

像这样使用依赖注入

ArrayList<Organism> foods = new ArrayList<Food>();
ArrayList<Organism> blobs = new ArrayList<Blob>();
ArrayList<Organism> predators = new ArrayList<Predator>();

public Organism pickTarget(Organism o){
    ArrayList<Organism> search = null;
    if(o instanceof Blob){
        search = foods;
    }
    else if(o instanceof Predator){
        search = blobs;
    }
    else if(o instanceof Food){
        search = predators;
    }

    if(search != null){
        Organism target = search.get(0);
        for(Organism organism:search){
            //do stuff to pick a target from assigned search space
        }

        return target;
    }
    return null; // in case something went wrong, you'll get null
}