为什么在java方法重写允许有协变返回类型,而不是协变参数? [英] Why in java method overriding allows to have covariant return types, but not covariant parameters?

查看:238
本文介绍了为什么在java方法重写允许有协变返回类型,而不是协变参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

For example I have a Processor base class with a method that returns an Object and takes Object as a parameter. I want to extend it and create a StringProcessor which will return String and take String as parameter. However covariant typing is only allowed with return value, but not parameter. What is the reason for such limitations?

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;
    }
}


推荐答案

< a href =https://en.wikipedia.org/wiki/Liskov_substitution_principle =noreferrer> Liskov原则。在设计Processor类时,你写了一个合同说:一个处理器能够将任何Object作为参数,并返回一个Object。

The Liskov principle. When designing the Processor class, you write a contract saying: "a Processor is able to take any Object as argument, and to return an Object".

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

The StringProcessor is a Processor. So it's supposed to obey that contract. But if it only accepts String as argument, it violates that contract. Remember: a Processor is supposed to accept any Object as argument.

所以你应该可以这样做:

So you should be able to do:

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

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

When returning a String, it doesn't violate the contract: it's supposed to return an Object, a String is an Object, so everything is fine.

你可以通过使用泛型来做你想要达到的目的:

You can do what you want to achieve by using generics:

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;
    }
}

这篇关于为什么在java方法重写允许有协变返回类型,而不是协变参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆