Java 尝试将对象存储在同一类型的变量中时,类型不兼容
我不明白为什么我可以返回一个实现接口的对象,但是编译器在试图将这个对象存储在这种类型的变量中时会抱怨 简单界面:Java 尝试将对象存储在同一类型的变量中时,类型不兼容,java,Java,我不明白为什么我可以返回一个实现接口的对象,但是编译器在试图将这个对象存储在这种类型的变量中时会抱怨 简单界面: public interface ITest { } public class Test implements ITest { } 现在是一个实现接口的简单类: public interface ITest { } public class Test implements ITest { } 好的,所以我的理解是:测试是ITest 现在的问题是: public cla
public interface ITest {
}
public class Test implements ITest {
}
现在是一个实现接口的简单类:
public interface ITest {
}
public class Test implements ITest {
}
好的,所以我的理解是:测试是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
}
}
变量测试来自型式测试,因此是ITest。我可以毫无怨言地将它传递给Tester.ParameterTestTest
但是尝试从Tester.returnValueTest中检索值并将其放入变量测试失败
不兼容类型:无法将ITest转换为Test
尽管该方法返回一个编译器不会抱怨的测试对象
为什么会这样?为什么我可以返回测试对象并与方法的返回类型ITest保持一致,但不能将此返回对象放入类型Test的变量中?您没有返回测试对象,而是返回了ITest实例
所有测试对象都实现了ITest,但并非所有ITest实例都必须是测试对象。要彻底了解这一点:我的误解是,我认为对象的继承是一个“小到大”的问题,但这是错误的思维方式 对象是关于接口的。比如说我们有一个可以生长的阶级生命体,我们有一个可以吠叫的阶级狗。以某种方式返回一个生命形式“适合”狗,但并非在所有情况下都符合狗的规格,因为不是每个生命形式都能吠叫。由于“变量类型”的含义只不过是“请放心,包含的对象实现了该类型指定的接口”,因此将非狗的生命形式放入狗类型的变量将违反此保证 因此,在这种情况下,如果一个方法通过签名返回一个生命形式,您不能将其放入Dog类型的变量中,因为它不一定是一只会吠叫的狗。您可以向编译器保证,通过强制转换返回的对象是一只狗,这样它就不会抱怨了。换句话说,通过施法,你告诉编译器他可以“放心,返回的生命形式是一只会吠叫的狗” 因此,在我的特殊情况下,我可以返回一个测试,因为它实现了接口ITest,每个人都可以确定,返回的对象将遵循ITest的规范,因此编译器不会抱怨。但是,除非编译器确信该对象确实实现了Test提供的接口,否则将该对象存储在Test类型的变量中的尝试将失败。所以我们必须投下它,一切都是彩虹和独角兽
Test test = (Test) Tester.returnValueTest();
但是我们应该注意这一点,因为它比仅仅使用正确类型的变量更容易出错。现在我明白了!我的想法是“较小的将适合较大的”,但这是错误的思维方式,认为ITest不满足测试规范,这就是问题所在。非常感谢。