Java 为什么编译器允许我将一个实现类转换为另一个实现类?
所以我一直在做向下投射,试图找出哪些有效,哪些无效。我有三个类:一个基类Java 为什么编译器允许我将一个实现类转换为另一个实现类?,java,inheritance,downcast,Java,Inheritance,Downcast,所以我一直在做向下投射,试图找出哪些有效,哪些无效。我有三个类:一个基类Animal,两个派生类Dog和Cat: private class Animal { } private class Dog extends Animal { } private class Cat extends Animal { } 编译器不允许使用以下代码,原因很明显: Dog dog = s.new Dog(); Cat cat = (Cat) dog; 这是因为我将一个派生类强制转换为另一个派生类,这是不
Animal
,两个派生类Dog
和Cat
:
private class Animal {
}
private class Dog extends Animal {
}
private class Cat extends Animal {
}
编译器不允许使用以下代码,原因很明显:
Dog dog = s.new Dog();
Cat cat = (Cat) dog;
这是因为我将一个派生类强制转换为另一个派生类,这是不可能的。但是,如果我将Animal
作为接口类型,将Cat
作为接口类型,那么编译器会突然接受它,并且不会说任何问题,即使这是不可能的
private interface Animal {
}
private class Dog implements Animal {
}
private interface Cat extends Animal {
}
当我像以前一样运行相同的代码时,它会像预期的那样给我一个错误。允许这样做的原因是,另一个类完全可能存在,如下所示:
class CatDog extends Dog implements Cat {
}
因为这样一个类可能存在,所以将任何(非
final
)类型的对象强制转换为任何接口类型都是合法的。我认为这里的问题是,接口Cat
不是一个实现,只是一个实现的规范,它与接口Animal
(尚未)没有区别。因此,将狗强制转换为Cat
接口没有错;这在runtimne是否有效则是另一回事。一个演员是你告诉编译器我更了解,你认为这是一个Foo
也是一个Bar
。我纠正了你相当混乱的术语。参考::-)