Java:如何拥有一个子类类型数组?

时间:2013-07-19 03:00:22

标签: java arrays inheritance subclass superclass

假设我有一个超级类“动物”和子类“Cat”,Dog,Bird“。有没有办法拥有一个子类类型数组而不是类实例,我将能够实例化每个实例的实例可能的子类?

为了简化,我想要这个:

Pseudo code: For each possible subclass of "Animal": create an instance of that class.

我该怎么做?

编辑:我不想要这些子类的实例数组,我想要一个对象类型的数组。

3 个答案:

答案 0 :(得分:3)

您可以使用Ploymorphism来实现这一目标。

Animal[] animalArray = new Animal[10];
animalArray[0] = new Dog();
animalArray[1] = new Cat();

基本上是动物类的所有子类。当你想要检索对象时,你可以简单地对其进行类型化

Dod dog = (Dog)animalArray[0];

要了解该类,您可以简单地使用getClass()方法。例如

    Animal[] animalArray = new Animal[10];
    animalArray[0] = new Dog();
    System.out.println(animalArray[0].getClass());

将打印class Dog

答案 1 :(得分:1)

OP评论后
即使使用反射,也没有办法获得类别的所有子类。但是你可以通过另一种方式来做,你可以说哪种方式是唯一但最长的方式。

  • 获取类路径中存在的所有类的名称列表
  • 加载每个类并测试它是否是所需类或接口的子类或实现者



在OP的评论之前回答

由于您的问题尚不清楚,但我想您想使用存储所有实例的数组或集合,即使它是superclasssubclass的实例。
然后我想你需要这样做。

List<Object> list = new ArrayList<Object>();
         list.add(new Cat());
         list.add(new Dog());
         list.add(new Animal());
         list.add(new Cat());

         for (int i = 0; i < list.size(); i++) {

             if(list.get(i) instanceof Cat){
                 System.out.println("Cat at "+i);
             }else if(list.get(i) instanceof Dog){
                 System.out.println("Dog at "+i);
             }else if(list.get(i) instanceof Animal){
                 System.out.println("Animal at "+i);
             }
        }

此代码已经过测试 注意:请记住,不要将示例代码(list.get(i) instanceof Animal)的父类检查放在顶部,否则它将通过两种情况(如果检查只是if-if-if )或跳过一个案例(如果检查是if-else if-else if,则始终将对象作为Animal返回)(list.get(i) instanceof Animal)(list.get(i) instanceof Cat)如果返回的对象是Cat对象。 < / p>

答案 2 :(得分:1)

正如另一个答案中所提到的,使用纯粹的反思是不可能的。

除非您可以自定义类以专门处理这种情况,否则您需要深入研究类加载器中的类,或者使用自定义类加载器将信息添加到内部数据结构中,以便在稍后请求您不必重复所有课程。

假设您对潜入类加载器代码不感兴趣(听起来您不是这样),那么下一个最好的方法是在类加载时运行静态代码。例如:

public class Animal {
    protected static List subclasses = new ArrayList();
    //...
}

public class Cat extends Animal {
    static { 
        subclasses.add(Cat.class);
    }
    //...
}

这基本上就是你用自定义类加载器做的事情,这个代码将存在于类加载器而不是类中。

对所有子类重复此模式。然后,当您想要创建实例时,在subclasses列表中有类引用,您可以使用Class.newInstance实例化(或者如果构造函数具有参数,则使用其他合适的反射方法)。