我不明白为什么我可以返回一个实现接口的对象,但编译器在尝试将该对象存储在该类型的变量中时会抱怨。简单的界面:public interface ITest {}现在是一个实现该接口的简单类:public class Test implements ITest {}好吧,我的理解是:ATest 是 ITest现在问题是:public class Tester { public static void parameterTest(ITest test) { } public static ITest returnValueTest() { return new Test(); // no compiler error here } public static void main(String[] args) { Test test = new Test(); Tester.parameterTest(test); test = Tester.returnValueTest(); // compiler complains here }}该变量test来自类型Test,因此ITest。我可以Tester.parameterTest(ITest test)毫无怨言地把它传递给你。但是尝试从变量中检索值Tester.returnValueTest()并将其放入变量中test会失败Incompatible types: ITest cannot be converted to Test尽管该方法返回一个Test编译器不会抱怨的对象。为什么这样?为什么我可以返回一个Test对象并符合方法的返回类型ITest,但不能将这个返回的对象放入类型的变量中Test?
2 回答
繁花不似锦
TA贡献1851条经验 获得超4个赞
说得更彻底一点:我的误解是,我认为对象的继承是“较小的适合较大的”的问题,但这是错误的思维方式。
对象是关于接口的。Lifeform
假设我们有一个可以的类grow()
,并且说我们有一个Dog
可以Lifeform
的类bark()
。以某种方式返回Lifeform
“适合” Dog
,但并非在所有情况下都满足规范,Dog
因为并非每个都Lifeform
可以bark()
。由于“变量的类型”的含义无非是“放心,所包含的对象实现了该类型指定的接口”,将“不是 a”放入Lifeform
类型Dog
变量Dog
中将违反这一保证。
因此,在这种情况下,如果方法返回Lifeform
by 签名,则不能将其放入类型变量中Dog
,因为它不一定是 aable Dog
to bark()
。您可以向编译器保证,返回的对象是Dog
通过强制转换返回的,那么它就不会抱怨。换句话说,通过强制转换,您可以告诉编译器他可以“放心,返回的Lifeform
是一个Dog
可以bark()
”。
因此,在我的特殊情况下,我可以返回 aTest
因为它实现了接口ITest
,并且每个人都可以确定,返回的对象将遵循 的规范ITest
,因此编译器不会抱怨。但是,Test
除非编译器确信该对象确实实现了Test
. 所以我们必须投射它,一切都是彩虹和独角兽。
Test test = (Test) Tester.returnValueTest();
但我们应该小心这一点,因为它比仅使用正确类型的变量更容易出错。
添加回答
举报
0/150
提交
取消