java - 如何为每个子类创建一个ArrayList?

时间:2017-12-11 15:15:18

标签: java android inheritance arraylist

我正在尝试创建一个可以被一个抽象类的所有子类使用的ArrayList,但是对象类型应该是sublcasses。

为简单起见,以下是一个例子:

有一个名为&#39; Animal&#39;的抽象类,有三个子类叫做&#39; Dog&#39;,&#39; Cat&#39;&#39; Pig&#39; 。 所以,我想创建一个&#39; ArrayList<Animal> all&#39;,子类应该使用此列表将对象存储在其列表中。 因此,必须有&#39; ArrayList<Dog>&#39;,&#39; ArrayList<Cat>&#39;和&#39; ArrayList<Pig>&#39;等等。 我不想循环通过动物&#39;动物&#39; class,然后转换每个对象导致非继承的方法和值无法访问......

我想这样做,这样我就可以更快地遍历对象。

3 个答案:

答案 0 :(得分:4)

要为每个子类型提供其类型列表,请将Animal设为通用。

在Animal.java中:

public class Animal<AnimalType extends Animal> {
    public List<AnimalType> getAll() {
        return all;
    }
    private List<AnimalType> all = new ArrayList<>();
}

在Dog.java中:

public class Dog extends Animal<Dog> {
    public void doSomething() {
        for (Dog dog: getAll()) {
        }
    }
}

通过使动物“通用”,您通常会想要参考您正在处理的特定动物类型。因此,如果您将变量声明为Animal类型,则需要包含类型信息(否则,您将收到有关原始类型的警告)。例如:

Animal<Dog> myFirstDog = ...;

如果你想引用一般的动物,那么你可能会这样做:

Animal<?> myFirstPet = ...;

如果你让你的动物等级更有趣也更通用,那么你可能会说:

Animal<? extends Canine> ...

可能与动物,动物或动物相匹配。

在最后一个例子中:

在Canine.java中:

public class Canine extends Animal<Canine> {
}

在Dog.java中:

public class Dog extends Canine<Dog> {
}

在Coyote.java中:

public class Coyote extends Canine<Coyote> {
}

答案 1 :(得分:0)

你应该使用泛型。例如:

class Animal<T> {
    List<T> all
}

class Cat extends Animal<Cat> {...}

我不确定您在扩展和超级关键字中的需求。在我的样本中,猫的列表只能包含猫,而不包含其他动物或猫的子类。

答案 2 :(得分:0)

我根据你的评论改写答案。你说

  

我想我没有解释清楚。我不需要为每个子类实例使用ArrayList,我需要为每个子类使用一个ArrayList(这意味着它将受到静态保护)。但是,我无法在超类中初始化它,因为我必须键入'ArrayList',而我需要ArrayList和ArrayList

您需要一个全局列表,您可以存储所有动物。再一次,我没有看到你在类层次结构中列出一个点,更不用说受保护的静态列表了。这意味着所有子类共享相同的列表 - 这意味着不可能像你想要的那样实现它。

为什么不将列表提取到存储库中然后将动物存储在那里?您可以随时将它们过滤到您需要的新动物列表中:

public class CrazyAnimalRepositry {

    private List<CrazyAnimal> animals = new ArrayList<>();

    public <T extends CrazyAnimal> List<T> filterForAnimalType(Class<T> filteringClass){
        return animals.stream()
                .filter(t -> t.getClass().equals(filteringClass))
                .map(t -> (T) t)
                .collect(Collectors.toList());
    }

    public void addAnimal(CrazyAnimal animal){
        animals.add(animal);
    }
}

您可以按如下方式使用此存储库:

public void testAnimals(){
    CrazyAnimalRepositry repositry = new CrazyAnimalRepositry();

    Dog dog = new Dog();
    Cat myCatz = new Cat();

    repositry.addAnimal(dog);
    repositry.addAnimal(myCatz);


    for(Cat cat : repositry.filterForAnimalType(Cat.class)){
        cat.meow();
    }
}

您还可以将存储库放在基类Crazy Animal中,并可以从那里访问同一个对象。从那里你可以通过调用 filterForanimalType 并传入你所在的课来过滤列表。