假设我有一个超类“动物”和子类“猫”,狗,鸟“。有没有办法拥有一个子类类型的数组而不是类实例,我可以用它来实例化每个可能的子类的实例?
为了简化,我想要这个:
Pseudo code: For each possible subclass of "Animal": create an instance of that class.
我怎样才能做到这一点?
编辑:我不想要这些子类的实例数组,我想要一个对象类型的数组。
假设我有一个超类“动物”和子类“猫”,狗,鸟“。有没有办法拥有一个子类类型的数组而不是类实例,我可以用它来实例化每个可能的子类的实例?
为了简化,我想要这个:
Pseudo code: For each possible subclass of "Animal": create an instance of that class.
我怎样才能做到这一点?
编辑:我不想要这些子类的实例数组,我想要一个对象类型的数组。
您可以使用多态来实现这一点。
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
。
在 OP 的评论之后,即使使用反射,也
没有办法获得一个类的所有子类型。
但是你可以通过另一种方式来做到这一点,你可以说这是唯一但最长的方式。
在OP评论之前回答
由于您的问题尚不清楚,但我想您想使用 array 或 Collection 来存储所有实例,即使它是superclass
or的实例subclass
。那我想你需要这样做。
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)(list.get(i) instanceof Animal)
并且(list.get(i) instanceof Cat)
如果返回的对象是 Cat 对象,则将对象作为 Animal返回。
正如另一个答案中提到的,使用纯粹的反射是不可能的。
除非您可以自定义类以专门处理这种情况,否则您需要深入研究从类加载器迭代类,或者使用自定义类加载器将信息添加到内部数据结构中,以便稍后请求时您不必重复所有课程。
假设您对深入研究类加载器代码不感兴趣(听起来您不感兴趣),那么下一个最佳方法是将静态代码添加到在类加载时运行的类中。例如:
public class Animal {
protected static List subclasses = new ArrayList();
//...
}
public class Cat extends Animal {
static {
subclasses.add(Cat.class);
}
//...
}
这基本上就是您使用自定义类加载器所做的事情,其中此代码将存在于类加载器中而不是类中。
对所有子类重复此模式。然后,当您要创建实例时,subclasses
列表中有类引用,您可以使用它来实例化Class.newInstance
(或者如果您的构造函数有参数,则使用另一种合适的反射方法)。