我有一个库,它使用作为输入的数据类型 X 构建 HashMap。它是 JGraphT 库。现在,我有两种类型的 X.Y 和 Z。所以 X 是一个超类。Y 和 Z 是 X 的子类。现在 X 是一个顶点。Y 和 Z 是特定类型的顶点。
现在,当我在 JGraphT 中构建图形并获取图形中任何边的源顶点时,我将其作为数据类型 X 获取。我想将其转换为数据类型 Y 和 Z,但简单的带括号的类型转换不起作用。我知道您不能以这种方式从超类对象转换为子类对象。但是有没有办法实现这一点?
我有一个库,它使用作为输入的数据类型 X 构建 HashMap。它是 JGraphT 库。现在,我有两种类型的 X.Y 和 Z。所以 X 是一个超类。Y 和 Z 是 X 的子类。现在 X 是一个顶点。Y 和 Z 是特定类型的顶点。
现在,当我在 JGraphT 中构建图形并获取图形中任何边的源顶点时,我将其作为数据类型 X 获取。我想将其转换为数据类型 Y 和 Z,但简单的带括号的类型转换不起作用。我知道您不能以这种方式从超类对象转换为子类对象。但是有没有办法实现这一点?
如果调用的结果实际上是 的实例,Y
您Z
可以使用instanceof
.
X x = someCall();
if (x instanceof Y) {
Y y = (Y)x;
y.doSomething();
}
else
if (x instanceof Z) { ... }
如果返回的 x 只是一个 X 而实际上不是 Y 或 Z,那么您需要根据 X 中的数据创建自己的 Y 或 Z(可能通过将 X 实例作为 arg 的构造函数)。
我想将它转换为数据类型 Y 和 Z,但简单的带括号的类型转换不起作用。
大概“简单的带括号的类型转换”的意思是这样的:
X myX = ...
Y myY = (Y) myX;
这称为“类型转换”。
它说“如果myX
确实是 的实例Y
,则将其分配给myY
”。如果引用的对象不是.myX
Y
我知道您不能以这种方式从超类对象转换为子类对象。
如果通过“转换”,您的意思与上述类型转换不同,那么这是正确的。
但是有没有办法实现这一点?
没有通用的方法可以将对象“转换”为不同于其实际类型或其实际类型的超类型的类型。这种“转换”只能通过编写一些方法来完成任务,并且必然需要创建一个不同的新对象。这是否明智(甚至可能)取决于应用程序。
(例如,如果实例表示图中的一个节点,那么创建一个新对象的“转换”将为您提供图的其他节点不引用的东西。这可能会破坏某些东西。)
1 - 您可以使用instanceof
测试来防范异常,但这不允许您将对象类型转换为它...不是其成员的类型。
解决此问题的一种方法是向 Y 和 Z 添加一个静态方法来执行您想要的操作:
class Y extends X {
...
public static Y toYType(X original) {
....
}
...
}
无论如何,您不能将同一个对象“转换”为子类,请考虑一下:Y 是 X 的一种特殊类型,可能带有额外的字段;如果您可以将 X“转换”为 Y,那么应该如何填写这些额外的字段?您需要显式创建一个新对象 Y
我知道您不能以这种方式从超类对象转换为子类对象。
没错,这被称为downcasting
并且仅在某些情况下才被允许且安全。有效向下转换的示例:
X x = (X)new Y(); // x is the result of upcasting of an object
// of type Y in the 1st place
Y y = (Y)x; // Allowed and safe in this specific case.
实现您的意思的一种方法是实现复制构造函数:
class X {
public int x, y, z;
public X() {
}
// Here the default copy cstor
public X(X src_x) {
this.x = src_x.x;
this.y = src_x.y;
this.z = src_x.z;
System.out.println("Cstor base copy called");
}
}
class Y extends X {
public int u;
// Here the copy cstor: sets x, y, z from x to this(type Y)
public Y(X x) {
super(x);
}
}
class Z extends X {
public int v;
// Here the copy cstor
public Z(X x) {
super(x);
}
}
然后你可以这样做:
X x = new X();
x.x = 1;
x.y = 2;
x.z = 3;
Y y = new Y(x);
但它与简单的类型转换相去甚远......