为了账号安全,请及时绑定邮箱和手机立即绑定

尝试将对象存储在该类型的变量中时,类型不兼容

尝试将对象存储在该类型的变量中时,类型不兼容

莫回无 2023-10-19 21:46:36
我不明白为什么我可以返回一个实现接口的对象,但编译器在尝试将该对象存储在该类型的变量中时会抱怨。简单的界面: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贡献2019条经验 获得超9个赞

您没有返回一个Test对象,而是返回一个ITest实例。

所有Test对象都实现ITest,但并非所有ITest实例都必须是Test对象。


查看完整回答
反对 回复 2023-10-19
?
繁花不似锦

TA贡献1851条经验 获得超4个赞

说得更彻底一点:我的误解是,我认为对象的继承是“较小的适合较大的”的问题,但这是错误的思维方式。

对象是关于接口的Lifeform假设我们有一个可以的类grow(),并且说我们有一个Dog可以Lifeform的类bark()。以某种方式返回Lifeform“适合” Dog,但并非在所有情况下都满足规范,Dog因为并非每个都Lifeform可以bark()。由于“变量的类型”的含义无非是“放心,所包含的对象实现了该类型指定的接口”,将“不是 a”放入Lifeform类型Dog变量Dog中将违反这一保证。

因此,在这种情况下,如果方法返回Lifeformby 签名,则不能将其放入类型变量中Dog,因为它不一定是 aable Dogto bark()。您可以向编译器保证,返回的对象是Dog通过强制转换返回的,那么它就不会抱怨。换句话说,通过强制转换,您可以告诉编译器他可以“放心,返回的Lifeform是一个Dog可以bark()”。


因此,在我的特殊情况下,我可以返回 aTest因为它实现了接口ITest,并且每个人都可以确定,返回的对象将遵循 的规范ITest,因此编译器不会抱怨。但是,Test除非编译器确信该对象确实实现了Test. 所以我们必须投射它,一切都是彩虹和独角兽。

Test test = (Test) Tester.returnValueTest();

但我们应该小心这一点,因为它比仅使用正确类型的变量更容易出错。


查看完整回答
反对 回复 2023-10-19
  • 2 回答
  • 0 关注
  • 96 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信