java接口引用了向下转换

时间:2016-02-06 05:06:23

标签: java interface

    interface A {}

    interface B{}

    interface C{}

    A a = new A(){};
    B b = (B)a;
    C c = (C)b;

即使这些接口不相关,上面的代码似乎也在编译,如果我将这些接口更改为类,则由于显而易见的原因而无法编译。为什么接口以这种方式运行

3 个答案:

答案 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 Aclass B的类。

另一个问题是final类。例如,您无法将String转换为Map,因为String的子类不能实现Map。但是您可以将DateArrayList投射到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