interface A {}
interface B{}
interface C{}
A a = new A(){};
B b = (B)a;
C c = (C)b;
即使这些接口不相关,上面的代码似乎也在编译,如果我将这些接口更改为类,则由于显而易见的原因而无法编译。为什么接口以这种方式运行
答案 0 :(得分:2)
我认为艾略特试图说的是,如果初始作业不同,这些演员可以成功。
class MyClass implements A, B, C {}
interface A {}
interface B{}
interface C{}
A a = new MyClass();
B b = (B)a;
C c = (C)b;
Java不支持多重继承,这就是不能使用类的原因。但由于接口可以多次实现,因此语法可能正常。
答案 1 :(得分:1)
接口是不相关的,但是可能有实现所有三个接口的类,因此可能存在可以快速转换的实例。
它不适用于类的原因是给定的类只能扩展一个超类,因此不能有任何扩展class A
和class B
的类。
另一个问题是final
类。例如,您无法将String
转换为Map
,因为String
的子类不能实现Map
。但是您可以将Date
或ArrayList
投射到Map
,因为可能存在适合的子类。
请注意,此推理仅适用于编译时。无效的强制转换在运行时仍会失败。编译时类型检查应该尽可能地捕获无效的强制转换,但并非所有情况都可以通过静态类型检查来检测(至少不是在Java中)。因此,除非编译器能够保证你的演员没有意义,否则它将允许它。
答案 2 :(得分:0)
要扩展我的评论,如果接口兼容,那么您的代码可能会在运行时成功。但是,如果接口不兼容,那么您可能会遇到灾难性的运行时错误。例如,
interface A {
int doIt(int a);
}
interface B {
float doIt(float b);
}
如果您随后提供实施 1
public static void main(String[] args) {
A a = new A() {
public int doIt(int a) {
return 2 * a;
}
};
B b = (B) a;
System.out.println(b.doIt(1));
}
在编译时,编译器相信您知道自己在做什么。并且很高兴您可以将a
投射到B
(然后分配给b
)。但是,在运行时,您会得到java.lang.ClassCastException
因为接口不兼容。
1 a
只是另一个java.lang.Object
实例,恰好实现了接口A