为什么在java方法重写允许有协变返回类型,而不是协变参数?

例如,我有一个Processor基类,其方法返回一个Object并将Object作为参数。 我想扩展它并创建一个StringProcessor,它将返回String并将String作为参数。 但是,协变类型仅允许返回值,但不允许参数。 这种限制的原因是什么?

class Processor { Object process (Object input) { //create a copy of input, modify it and return it return copy; } } class StringProcessor extends Processor { @Override String process (String input) { // permitted for parameter. why? //create a copy of input string, modify it and return it return copy; } } 

利斯科夫原则 。 在设计Processor类时,您编写了一个合同,说:“处理器能够将任何Object作为参数,并返回一个Object”。

StringProcessor是一个处理器。 所以它应该服从那份合同。 但如果它只接受String作为参数,则违反该合同。 请记住:处理器应该接受任何Object作为参数。

所以你应该能够做到:

 StringProcessor sp = new StringProcessor(); Processor p = sp; // OK since a StringProcessor is a Processor p.process(new Integer(3456)); 

返回String时,它不违反合同:它应该返回一个Object,一个String是一个Object,所以一切都很好。

您可以使用generics执行您想要实现的目标:

 class Processor { Object process (T input) { //create a copy of input, modify it and return it return copy; } } class StringProcessor extends Processor { @Override String process (String input) { return copy; } } 

此外,如果你想要一个类型理论答案,其原因是,当考虑函数类型的子类型关系时,关系在返回类型上是协变的,但在参数类型上是逆变的 (即X -> YU -> W的子类型) U -> W如果YU -> W的子类型而UX的子类型。