Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 尝试将对象存储在同一类型的变量中时,类型不兼容_Java - Fatal编程技术网

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不满足测试规范,这就是问题所在。非常感谢。