[英]java interface references downcasting
interface A {}
interface B{}
interface C{}
A a = new A(){};
B b = (B)a;
C c = (C)b;
即使这些接口不相关,上面的代码似乎也可以编译。如果我将这些接口更改为类,则出于明显的原因它不会编译。 为什么界面的行为方式如此
我认为艾略特(Eliot)试图说的是,如果最初的任务不同,那么这些演员可能会成功。
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不支持多重继承,这就是为什么它不能与类一起使用的原因。 但是由于可以多重实现接口,因此语法可能还可以。
这些接口是无关的,但是可能存在实现所有这三个接口的类,因此可能会有一些实例可以轻松地进行转换。
它不适用于类的原因是给定的类只能扩展一个超类,因此不能有任何类同时扩展class A
和class B
final
一个是final
课程。 例如,您不能将String
为Map
因为不能存在实现Map
的String
子类。 但是您可以将Date
或ArrayList
为Map
因为可能存在适合的子类。
请注意,这种推理仅适用于编译时。 无效的强制转换仍将在运行时失败。 编译时类型检查应该尽可能多地捕获无效的类型转换,但是并非所有情况都可以通过静态类型检查来检测(至少在Java中不是)。 因此,除非编译器可以保证您的强制转换没有意义,否则它将允许它。
进一步说一下,如果接口兼容,那么您的代码很可能会在运行时成功。 但是,如果接口不兼容,则可能会遇到灾难性的运行时错误。 例如,
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.