Java 接口和协变返回类型
以下代码未编译,在Java 接口和协变返回类型,java,inheritance,Java,Inheritance,以下代码未编译,在第1行出现以下错误 返回类型与B.m1()不兼容 现在,我的查询是对象和字符串都是协变的,而类C是抽象类。那么,尽管我同时实现了A和B接口方法,为什么会出现这种编译错误呢 因为如果C是B,那么我希望从m1返回字符串。因此,B作为A工作,但反之亦然。所以C不起作用 final A a = new C(){}; final Object res = a.m1(); //fine, `m1` returns an `Object`. final B b = new C(){}; f
第1行出现以下错误
返回类型与B.m1()不兼容
现在,我的查询是对象
和字符串
都是协变的
,而类C
是抽象类。那么,尽管我同时实现了A
和B
接口方法,为什么会出现这种编译错误呢
因为如果C
是B
,那么我希望从m1
返回字符串。因此,B
作为A
工作,但反之亦然。所以C
不起作用
final A a = new C(){};
final Object res = a.m1(); //fine, `m1` returns an `Object`.
final B b = new C(){};
final String res = b.m1(); //bang
这里我们看到B
从m1()
返回字符串,但您的实现返回对象。编译程序不允许这种情况发生
看。如果C
是B
,那么无论我在哪里有B
,我都应该能够用C
替换它-在您的示例中,情况并非如此
这会管用的,你知道为什么吗
abstract class C implements A, B {
@Override
public String m1() {
return "";
}
}
如果你将void作为一种返回类型,它将很好地工作。不,问题请尝试找到答案并澄清我的疑问:)<代码>C
不起作用。因为如果C
是B
,那么我希望从m1
返回字符串。因此,B
作为A
工作,但反之亦然。所以C
不起作用。看。这不是关于哪个不起作用,而是关于为什么它不起作用?因为你没有这样做-它是反变的。是的,你是对的,这起作用了…:)奇怪,我需要检查并理解你的答案。我要求你告诉我们为什么第二个案例起作用,不能understand@LoneWolf我认为你自己解决这个问题会更有用。阅读关于Liskov的文章,然后应用我在上面所做的相同逻辑。“如果C
是B
,那么无论我在哪里有B
,我都应该能够用C
替换它。”。不一定是因为B
可以是C
或B
的任何子级。不应该是:“如果C
是B
,那么无论哪里有C
,我都应该能够用B
替换它。”?@davidxxx通常不能将子类的每个实例都替换为超类-例如,如果您有ArrayList
,则不能将它们全部替换为Collection
。但是反过来应该是正确的是ArrayList
是一个集合
。
abstract class C implements A, B {
@Override
public String m1() {
return "";
}
}