作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
想象一下超 A 类:
public class A {
private int x;
A(int x){
this.x = x;
}
public int getX() {
return x;
}
}
它有 2 个子类 B 和 C:
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 关系。
这主要是因为您尝试使用父类(super class)来迭代来描述所有内容。
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);
}
}
关于Java:如何将克隆对象转换为其原始子类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59363402/
我是一名优秀的程序员,十分优秀!