让我解释一下:
package a.b.c.d;
public interface ObjA extends ObjFirst ...
然后
package e.f.g.h;
public interface ObjB extends a.b.c.d.ObjA ...
我有一个来自包a.b.c.d的方法,它返回一个ObjA,当我尝试隐式地将它转换为ObjB时,它返回错误:
Type mismatch: cannot convert from a.b.c.d.ObjA to e.f.g.h.ObjB
我哪里错了?
答案 0 :(得分:4)
你要做的事情被称为" downcast",并且编译器不会让你隐式地这样做。那是因为编译器不知道ObjA
的实例是否也是ObjB
的实例。
让我们以此为例:
class Animal {
//...
}
class Dog extends Animal {
//...
}
class Cat extends Animal {
//...
}
Dog
is-an Animal
,Cat
is-an Animal
。
所以你可以这样做:
Cat cat = new Cat();
Animal animal = c;
但你无法做到:
Animal animal = new Animal();
Cat cat = animal;
事实上,试着考虑一下。如果我告诉你"我有动物",你怎么能确定是猫?
如果你想垂头丧气,你必须明确地做:
/*
* Here myAnimal is an Animal. In order to cast,
* I **must** be sure that myAnimal is a cat.
*/
Cat cat = (Cat) myAnimal;
为了确保myAnimal
是Cat
:
if(myAnimal instanceof Cat) {
Cat cat = (Cat) myAnimal;
// do whatever you need to do with that cat object
}
答案 1 :(得分:1)
由于ObjB
是ObjA
的子接口,因此您无法将ObjA
个实例传递给期望ObjB
个实例而没有显式强制转换的方法/变量,因为并非所有ObjA
个实例都是ObjB
个实例(您可能有ObjC
个扩展ObjA
并且未实现ObjB
的接口。)
您应该检查变量的类型(使用var instanceof ObjB
),然后显式转换为ObjB
(使用(ObjB) var
)。
答案 2 :(得分:1)
ObjB了解ObjA和ObjFirst
ObjA了解ObjFirst
但是在这里我们试图将ObjA投射到它不知道的ObjB。 我们可以通过使用" instanceof"来检查这个问题。操作
ObjB instanceof ObjA是真的
ObjA instanceof ObjB返回false
答案 3 :(得分:0)
您需要主动投射它,因为不支持向下转换。通过尝试向下转换,您隐含地期望系统尝试在可以最好地描述为继承树的东西中找到接口。问题是,如果支持向下转换,那么无论何时使用某种任意类型的对象,系统都应该总是尝试找到与之匹配的子类/子接口。它可以支持与否。在我们的情况下它不受支持,我相信这是一件非常好的事情。如果没有这样的子类,子接口怎么办?这可能是一个运行时异常,可能是在代码已经发布时。