Java 从超类型向后投射到子类型

Java 从超类型向后投射到子类型,java,casting,Java,Casting,假设我有一个超级类型(形状)和两个孩子(像正方形、圆形) 我正试着做这样的事情: Shape shape = someObject.getShape(); if (shape instanceof Square){ shape = (Square) shape; // do this } else if (shape instanceof Circle) { shape = (Circle) shape; // do that } 另外,由于获取实例似乎不是一

假设我有一个超级类型(形状)和两个孩子(像正方形、圆形)

我正试着做这样的事情:

Shape shape = someObject.getShape();

if (shape instanceof Square){
    shape = (Square) shape;
    // do this
} else if (shape instanceof Circle) {
    shape = (Circle) shape;
    // do that
}
另外,由于获取实例似乎不是一个正确的OO原则,有没有其他方法可以做到这一点?干杯

编辑。我不想调用它们的方法,我想把它们传递给一些需要它们特定子类型的方法


edit2基本上我有一个类型形状的集合,所以我可以在其中保存两种类型的子类型。但是当涉及到某一点的处理时,我需要知道这两个子类中的哪一个是,这样我就可以将它传递给一个将子类型作为参数的方法。我可以轻松地使用超类型作为参数,但这并不安全,因为我处理的是特定于子类型的数据。

您需要正确声明变量,例如:

if (shape instanceof Square){
    Square square = (Square) shape;
    // do this with square
} else if (shape instanceof Circle) {
    Circle circle = (Circle) shape;
    // do that with circle
}

一旦用Java声明了引用,就不能更改其类型。当您这样做时:

Shape shape = someObject.getShape();
您的意思是:“在变量形状中存储对形状的引用”。因为你不能改变它的类型,所以这样做没有意义

shape = (Square) shape;
因为你说的形状(左边)是一个形状,不管作业右边是什么


记住:一旦你为引用声明了一个类型,你就不能更改它。

我真的不明白你在这里想要实现什么,但是你当然可以在不同的情况下以

shape.getClass().isAssignableFrom(Square.class) ? processSquare((Square)shape) : processCircle((Circle)shape)
如果您首先检查实际的类,则该强制转换不会有问题

编辑您的形状类类型不会更改:

Shape[] shapes = new Shape[]{new Circle()}

当您在shapes集合中循环时,当您调用
shapes[0].getClass()
时,您将得到
圆圈.class
类型。因此,在迭代shape集合并需要决定调用哪种类型的特定集合时,您可以调用
shape.getClass().isAssignableFrom(Circle.class)
,例如,切换大小写。然后可以强制转换类型并调用所需的方法。不需要在不同的集合中保存形状对象

您可能需要创建一个新实例,如
Square;如果(shape instanceof Square){Square=(Square)shape;//do this}
更好的OO原则是在它们的公共超类型中有一个共享的抽象方法。然后,不管实际形状是什么,都可以使用supertype声明调用特定于类的方法。问题是我不想调用任何方法,而是要将此对象传递给另一个需要特定子类型的方法。我认为使用相同的变量来保存它自己。可能无法做到这一点:/Java中,您可以调用声明为变量类型的方法,而不是实际的assigne dobject。如果某些方法被重写,它们的新版本将被调用。是的,我知道,我只需要将子类型传递给不同的方法,这些方法对那些特定的类类型具有特定的参数…我认为,Shape不是Sqare或Circle的实例,是吗?我认为你的应用程序设计有点混乱。但是,除此之外,就像已经展示的那样,实例的actuel类类型不会改变,尽管您存储它的是超类型变量。我会编辑我的帖子来澄清我的形状对象不在不同的集合中,我什么时候说的我有一个阵列。我有一个方法,比如cutSquareInHalf(Square sq)。因此,当我从集合中得到一个形状对象时,我需要知道它是否是一个正方形,以便我可以投射它并通过该方法传递它。标记为正确答案的帖子告诉你这样做。我认为这样做没有任何好处。“我需要知道它是否实际上是一个正方形”->shapes[0]。getClass().isAssignableFrom(square.class)->如果该类与参数类相同或是超类型,则返回true。那有什么问题?如果你给我一个关于这个解决方案的论点,我会尝试提出一些不同的解决方案:)我更喜欢instanceof,因为它对任何子类型都返回true。我很确定你的代码也能正常工作,但我从一开始就这样实现了:)我之前的评论只是针对你的最后一句话“不需要在不同的集合中保存形状对象”