繁体   English   中英

如何获得将超类对象转换为子类对象的效果?

[英]How do I achieve the effect of converting a super class object to a subclass object?

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

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

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

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

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

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

那就是所谓的“ 类型转换 ”。

它说:“如果myX确实是Y的实例,则将其分配给myY ”。 如果myX引用的对象不是Y的实例,则类型转换将失败(运行时异常为1 )。

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

如果“转换”是指与上述类型转换有所不同 ,那是正确的。

但是有什么办法可以做到这一点?

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

(例如,如果该实例表示图形中的一个节点,则创建新对象的“转换”将为您提供图形中其他节点未引用的某些内容。这很容易破坏某些内容。)


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);

但这离简单的类型转换还差得远...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM