什么是协变返回types?
什么是Java中的协变返回types? 在一般的面向对象编程中?
Covariant返回,意味着当一个覆盖方法时,覆盖方法的返回types被允许成为覆盖方法的返回types的子types。
为了用一个例子来说明这个问题,常见的情况是Object.clone()
– 它被声明为返回一个Object
types。 你可以在你自己的类中覆盖它,如下所示:
public class MyFoo { ... // Note covariant return here, method does not just return Object public MyFoo clone() { // Implementation } }
这里的好处是任何持有对MyFoo对象的明确引用的方法都能够调用clone()
并知道(不用强制转换)返回值是MyFoo
一个实例。 如果没有协变返回types,MyFoo中的重载方法将被声明为返回Object
– 因此调用代码将不得不显式地下调方法调用的结果(甚至认为双方“知道”它只能是MyFoo)。
请注意, clone()
没有什么特别之处,任何重写的方法都可以有一个协变的返回 – 我在这里用它作为示例,因为它是一个常用的标准方法。
这是另一个简单的例子:
Animal
类
public class Animal { protected Food seekFood() { return new Food(); } }
Dog
类
public class Dog extends Animal { @Override protected Food seekFood() { return new DogFood(); } }
可以将Dog
的seekFood()
方法的返回types修改为DogFood
– Food
一个子类,如下所示:
@Override protected DogFood seekFood() { return new DogFood(); }
这完全是一个合法的重写, Dog
的seekFood()
方法的返回types被称为协变返回types 。
从JDK 1.5发布以来,Java中引入了协变types。 我会用一个简单的例子来向你解释: 当我们重写一个函数时,函数允许改变它的行为 ,这是你在大多数书中读到的,但是他们错过了什么是我们也可以改变返回types。 检查下面的链接澄清我们可以改变返回types,只要它可以被分配给方法的基本版本的返回types。
所以这个返回派生types的特性叫做COVARIANT …
返回types可以重写的方法有所不同吗?
协变返回types仅仅意味着返回自己的类引用或其子类的引用。 class Parent {//它包含数据成员和数据方法}
class Child extends Parent { //it contain data member and data method //covariant return public Parent methodName() { return new Parent(); or return Child(); } }
- java中的协变返回types允许缩小重写方法的返回types。
- 这个function将有助于避免在客户端进行强制转换。 它允许程序员进行编程而不需要types检查和下载转换。
- 协变返回types总是只对非原始返回types起作用。
interface Interviewer { default Object submitInterviewStatus() { System.out.println("Interviewer:Accept"); return "Interviewer:Accept"; } } class Manager implements Interviewer { @Override public String submitInterviewStatus() { System.out.println("Manager:Accept"); return "Manager:Accept"; } } class Project { public static void main(String args[]) { Interviewer interviewer = new Manager(); interviewer.submitInterviewStatus(); Manager mgr = new Manager(); mgr.submitInterviewStatus(); } }
其他的例子是来自Java,
UnaryOperator.java
@FunctionalInterface public interface UnaryOperator<T> extends Function<T, T> { /** * Returns a unary operator that always returns its input argument. * * @param <T> the type of the input and output of the operator * @return a unary operator that always returns its input argument */ static <T> UnaryOperator<T> identity() { return t -> t; } }
Function.java
@FunctionalInterface public interface Function<T, R> { ........ ........ ........ ........ static <T> Function<T, T> identity() { return t -> t; } }
Covariant return type specifies that the return type may vary in the same direction as the subclas class One{ One get(){return this;} } class Two extends One{ Two get(){return this;} void message(){System.out.println("After Java5 welcome to covariant return type");} public static void main(String args[]){ new Two().get().message(); } } Before Java5,
通过改变返回types来覆盖任何方法是不可能的。 但是现在,从Java5开始,
如果子类重写任何返回types为Non-Primitive的方法,但它将返回types更改为子types,则可以通过更改返回types来覆盖方法。