繁体   English   中英

java接口引用向下转换

[英]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 Aclass B

final一个是final课程。 例如,您不能将StringMap因为不能存在实现MapString子类。 但是您可以将DateArrayListMap因为可能存在适合的子类。

请注意,这种推理仅适用于编译时。 无效的强制转换仍将在运行时失败。 编译时类型检查应该尽可能多地捕获无效的类型转换,但是并非所有情况都可以通过静态类型检查来检测(至少在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM