1

我有一个库,它使用作为输入的数据类型 X 构建 HashMap。它是 JGraphT 库。现在,我有两种类型的 X.Y 和 Z。所以 X 是一个超类。Y 和 Z 是 X 的子类。现在 X 是一个顶点。Y 和 Z 是特定类型的顶点。

现在,当我在 JGraphT 中构建图形并获取图形中任何边的源顶点时,我将其作为数据类型 X 获取。我想将其转换为数据类型 Y 和 Z,但简单的带括号的类型转换不起作用。我知道您不能以这种方式从超类对象转换为子类对象。但是有没有办法实现这一点?

4

4 回答 4

0

如果调用的结果实际上是 的实例,YZ可以使用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 的构造函数)。

于 2013-06-25T01:29:18.127 回答
0

我想将它转换为数据类型 Y 和 Z,但简单的带括号的类型转换不起作用。

大概“简单的带括号的类型转换”的意思是这样的:

X myX = ...
Y myY = (Y) myX;

这称为“类型转换”。

它说“如果myX确实是 的实例Y,则将其分配给myY”。如果引用的对象不是.myXY

我知道您不能以这种方式从超类对象转换为子类对象。

如果通过“转换”,您的意思与上述类型转换不同,那么这是正确的。

但是有没有办法实现这一点?

没有通用的方法可以将对象“转换”为不同于其实际类型或其实际类型的超类型的类型。这种“转换”只能通过编写一些方法来完成任务,并且必然需要创建一个不同的新对象。这是否明智(甚至可能)取决于应用程序。

(例如,如果实例表示图中的一个节点,那么创建一个新对象的“转换”将为您提供图的其他节点不引用的东西。这可能会破坏某些东西。)


1 - 您可以使用instanceof测试来防范异常,但这不允许您将对象类型转换为它...不是其成员的类型。

于 2013-06-25T01:32:18.487 回答
0

解决此问题的一种方法是向 Y 和 Z 添加一个静态方法来执行您想要的操作:

    class Y extends X {
    ...
            public static Y toYType(X original) {
                ....
            }
    ...
    }

无论如何,您不能将同一个对象“转换”为子类,请考虑一下:Y 是 X 的一种特殊类型,可能带有额外的字段;如果您可以将 X“转换”为 Y,那么应该如何填写这些额外的字段?您需要显式创建一个新对象 Y

于 2013-06-25T01:36:02.960 回答
0

我知道您不能以这种方式从超类对象转换为子类对象。

没错,这被称为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);

但它与简单的类型转换相去甚远......

于 2013-06-25T01:41:56.303 回答