【发布时间】:2016-02-18 18:27:41
【问题描述】:
我正在研究 Java 中的强制转换,特别是使用接口进行强制转换。假设我有一个接口I,它定义了一个方法跳转,即:
interface I{
public void jump();
}
另外假设我还有 3 个其他类,A、B 和 C。 A 实现 I。 B 没有。但是,C 扩展了B 并实现了I。
class A implements I {
public void jump(){
System.out.print("A is jumping");
}
}
class B { }
class C extends B implements I {
public void jump(){
System.out.print("C is jumping");
}
}
现在,如果我尝试将A 类型的对象分配给I,没有问题,我什至不需要演员表。即:
I i = new A();
没问题,不需要强制转换。
大概这是因为编译器知道 A 实现了 I。此外,如果我尝试这样做:
A mya = new A();
I i = mya;
没有问题,即使mya 可能引用A 的子类。但是 AFAIK 没关系,因为编译器知道 A 的每个子类都必须隐式实现 jump 方法,因此接口 A。
但是,如果我尝试将B 类型的对象分配给I,那么我确实需要一个演员表。例如
B myb = new B();
I i = (I)myb;
大概这是因为编译器知道B 没有实现I。然而,由于B 可以引用实现I 的子类,因此您可以转换为I。到现在为止还挺好。
现在这是我的问题:如果我想将引用C(实现I)类型的对象的B 类型的对象分配给I,那么我们需要一个演员表。这是为什么?例如。
B b = new C();
I myI = b; //Won't compile this needs a cast
I myI = (C)b; // This will compile
myI = (I)b; // This will also compile
为什么编译器不明白 B 指的是实现 I 的 C?
大概是因为B 可以引用B,它实际上并没有实现I,但是为什么编译器不知道呢?大概编译器仅限于每行可用的信息?它无法运行您的程序并看到b 实际上指向C?如果这是正确的,有人可以指出一些关于 Java 编译器如何工作以及它们的局限性的文献的方向吗?
【问题讨论】: