Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java接口引用向下转换_Java_Interface - Fatal编程技术网

java接口引用向下转换

java接口引用向下转换,java,interface,Java,Interface,尽管这些接口不相关,但上面的代码似乎是编译的,如果我将这些接口更改为类,它显然不会编译。为什么接口的行为是这样的我想Eliot想说的是,如果初始分配不同,这些强制转换可能会成功 interface A {} interface B{} interface C{} A a = new A(){}; B b = (B)a; C c = (C)b; Java不支持多重继承,这就是它不能处理类的原因。但是,由于接口可以被多次实现,语法可能还可以。我

尽管这些接口不相关,但上面的代码似乎是编译的,如果我将这些接口更改为类,它显然不会编译。为什么接口的行为是这样的

我想Eliot想说的是,如果初始分配不同,这些强制转换可能会成功

    interface A {}

    interface B{}

    interface C{}

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

Java不支持多重继承,这就是它不能处理类的原因。但是,由于接口可以被多次实现,语法可能还可以。

我想Eliot想说的是,如果初始赋值不同,这些强制转换可能会成功

    interface A {}

    interface B{}

    interface C{}

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

Java不支持多重继承,这就是它不能处理类的原因。但是,由于接口可以多次实现,因此语法可能还可以。

在我的评论中,如果接口兼容,那么代码在运行时可能会成功。但是,如果接口不兼容,那么您可能会遇到灾难性的运行时错误。比如说,

class MyClass implements A, B, C {}

interface A {}

interface B{}

interface C{}

A a = new MyClass();
B b = (B)a;
C c = (C)b;
如果随后提供实现1

在编译时,编译器相信您知道自己在做什么。并允许您将
a
转换为
B
(然后分配给
B
)。但是,在运行时会得到
java.lang.ClassCastException
,因为接口不兼容


1
a
只是另一个
java.lang.Object
实例,它碰巧实现了接口
a

,根据我的评论,如果接口兼容,那么您的代码在运行时可能会成功。但是,如果接口不兼容,那么您可能会遇到灾难性的运行时错误。比如说,

class MyClass implements A, B, C {}

interface A {}

interface B{}

interface C{}

A a = new MyClass();
B b = (B)a;
C c = (C)b;
如果随后提供实现1

在编译时,编译器相信您知道自己在做什么。并允许您将
a
转换为
B
(然后分配给
B
)。但是,在运行时会得到
java.lang.ClassCastException
,因为接口不兼容


1
a
只是另一个
java.lang.Object
实例,它碰巧实现了接口
a

接口是不相关的,但是可能有实现所有三个接口的类,所以可能有可以愉快地转换的实例

它不适用于类的原因是给定的类只能扩展一个超类,因此不能有任何类同时扩展
类a
类B

关于这一点的另一个说法是
final
类。例如,您不能将
String
强制转换为
Map
,因为
String
的子类不能实现
Map
。但是您可以将
Date
ArrayList
强制转换为
Map
,因为可能存在适合的子类


请注意,此推理仅适用于编译时。无效的强制转换仍将在运行时失败。编译时类型检查应该尽可能多地捕获无效的强制转换,但并不是所有情况都可以通过静态类型检查检测到(至少在Java中不是这样)。因此,除非编译器能够保证您的强制转换没有意义,否则它将允许您这样做。

接口是不相关的,但可能有实现所有三个接口的类,因此可能有可以愉快地强制转换的实例

它不适用于类的原因是给定的类只能扩展一个超类,因此不能有任何类同时扩展
类a
类B

关于这一点的另一个说法是
final
类。例如,您不能将
String
强制转换为
Map
,因为
String
的子类不能实现
Map
。但是您可以将
Date
ArrayList
强制转换为
Map
,因为可能存在适合的子类


请注意,此推理仅适用于编译时。无效的强制转换仍将在运行时失败。编译时类型检查应该尽可能多地捕获无效的强制转换,但并不是所有情况都可以通过静态类型检查检测到(至少在Java中不是这样)。因此,除非编译器能够保证您的强制转换没有意义,否则它将允许它。

尝试使
A
B
(和
C
)不兼容(而不是简单的标记接口)。在Java中,一切(不是原语值)都继承自
Java.lang.Object
我做了以下更改。接口A{void test();}接口B{void fun();}接口C{void hi();}仍然存在相同的问题。此外,从java.lang.Object扩展的所有内容都不是一个合理的解释,因为如果我将这些接口更改为类,它确实会给出预期的编译错误“不兼容”,即在所有三个接口中都有一个
test()
方法,但具有不同的(且不兼容)属性返回类型。@Thilo-我确实使返回类型与所有三个具有测试方法的接口不兼容。但代码仍然可以编译。所以不兼容似乎不是这里的解释。如果我错了,请纠正我。然而,您在下面给出的多重继承推理开始有意义了,“它不编译是因为明显的原因”,这对编译器来说并不明显。编译器只看到您将
A
转换为
B
A
转换为
C
。它不知道
a
b
中的实际内容。(如果
a
是一个方法的参数会怎样?)“为什么接口会这样做”接口的行为方式实际上是规范。类的行为方式是这样的,因为编译器有更多的信息,可以查看层次结构。有时,编译器可以判断特定的强制转换永远不会成功,但这是规则的例外。大多数情况下,编译器不知道