例如,我有一个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;
}
}
答案 0 :(得分:10)
The Liskov principle。在设计Processor类时,你写了一个合同说:“一个处理器能够将任何Object作为参数,并返回一个Object”。
StringProcessor是一个处理器。所以它应该服从那份合同。但如果它只接受String作为参数,它就违反了该合同。请记住:处理器应该接受任何Object作为参数。
所以你应该能够做到:
class Processor<T> {
Object process (T input) {
//create a copy of input, modify it and return it
return copy;
}
}
class StringProcessor extends Processor<String> {
@Override
String process (String input) {
return copy;
}
}
返回String时,它不违反合同:它应该返回一个Object,一个String就是一个Object,所以一切都很好。
您可以使用泛型来实现您想要达到的目标:
10,000! ~= 10^36,000
答案 1 :(得分:0)
另外,如果你想要一个类型理论答案,原因是,当考虑函数类型的子类型关系时,关系在返回类型上是协变的,但在参数类型上是逆变(如果X -> Y
是U -> W
的子类型且Y
是W
的子类型,则U
是X
的子类型。