想象一下超级A类:
public class A {
private int x;
A(int x){
this.x = x;
}
public int getX() {
return x;
}
}
它是B和C的2个子类:
public class B extends A{
private int y = 2;
B(int x){
super(x);
}
}
public class C extends A{
private int y = 3;
B(int x){
super(x);
}
}
现在想象一下所有都继承类A的对象列表。我想遍历该列表并克隆每个对象,然后将其强制转换为它的原始子类(B或C)。这就是我试图做到的方式:
public static void main(String args[]) {
ArrayList<A> aList = new ArrayList<A>();
aList.add(new B(5));
aList.add(new C(6));
ArrayList<A> aClones = new ArrayList<A>();
for(A a : aList) {
A aNew = new A(a.getX());
a.getClass().cast(aNew);
aClones.add(aNew);
}
}
但这给我一个错误,说我不能将A强制转换为B。如何在不预先知道要处理的对象子类型的情况下实现此目标?我可以在for循环内为每种类型的子类执行if语句,以检查
a
是否是该子类的实例,然后简单地创建该特定子类的新实例并以这种方式克隆它。但是,在我的情况下,将有更多的子类,而不仅仅是B和C,并且可能还会有更多的子类。我不希望for循环包含有关A的现有子类的任何知识。这可能吗? 最佳答案
这无法以您编写的方式完成。
原因很简单:B
和C
与A
具有is-a关系,但是A
与B
或C
没有相同的is-a关系。
这主要是因为您要尝试使用超类来描述所有内容。
for(A a : aList) { }
在进行迭代时,您无法仅凭类型推断就无法知道具体的类
A
是什么。因此,这失败了,正如预期的那样。
a.getClass().cast(aNew);
如果没有明确询问类是什么类型,则无法执行此操作。
这意味着,如果您打算对此进行扩展,将会编写很多
instanceof
语句。for(A a : aList) {
if(a instanceof B) {
B b = new B(a.getX());
aClones.add(b);
}
if(a instanceof C) {
C c = new C(a.getX());
aClones.add(c);
}
}