在关于interfaces的Oracle教程之后,我尝试了代码并添加了一个moveAll方法,该方法将所有矩形(作为varargs)移动到已解析的位置。
public static void moveAll(int x, int y, Relatable... obj) {
Rectangle[] rects = (Rectangle[])obj;
for(Rectangle r: rects){
r.move(x, y);
}
}
public interface Relatable {
public static void moveAll( int x, int y, Relatable... obj) {}
}
编译后我得到:
Exception in thread "main" java.lang.ClassCastException: [Linterfaces.Relatable; cannot be cast to [Linterfaces.RectanglePlus;
at interfaces.RectanglePlus.moveAll(RectanglePlus.java:52)
at interfaces.Main.main(Main.java:9)
答案 0 :(得分:1)
假设Rectangle类实现了Relatable接口并且Rectangle类具有move(int x,int y)方法,则会得到ClassCastException,因为即使Rectangle实现了Relatable,也不能将Relatable数组视为Rectangle数组。 Java数组是协变的,这意味着允许它做这样的事情:
Integer.MIN
不管B []不是A []的子类。 Relatable []和Rectangle []都直接从Object派生(与任何其他数组类型一样),因此它们之间没有父子关系。
就您的示例而言,以下是一些解决此问题的不同方法:
1。 您可以在其上投射每个元素
public class A {...}
public class B extends A{...}
A[] array = new B[2];
2。您可以使用多态来改进上面的代码。要做到这一点,你必须在Relatable接口中声明move方法。我们现在可以拒绝转换,因为每个实现Relatable的类都必须实现 move(int x,int y) 方法(否则我们会得到java.lang.UnsupportedOperationException )
public static void moveAll( int x, int y, Relatable... obj) {
for(Relatable r: obj){
((Rectangle)r).move(x, y);
}
}
希望这有帮助:)