什么是协变返回值类型?

什么是爪哇协变返回值类型? 一般的面向对象程序设计?

85730 次浏览

协变返回,意味着当重写方法时,重写方法的返回类型允许是重写方法的返回类型的子类型。

为了说明这一点,举个例子,一个常见的例子是 Object.clone()-它被声明为返回 Object的类型。您可以在自己的类中重写它,如下所示:

public class MyFoo
{


...


// Note covariant return here, method does not just return Object
public MyFoo clone()
{
// Implementation
}
}

这里的好处是,任何保存对 MyFoo 对象的显式引用的方法都能够调用 clone(),并且(不需要强制转换)知道返回值是 MyFoo的一个实例。如果没有协变返回类型,MyFoo 中重写的方法必须声明为返回 Object-因此调用代码必须显式地降低方法调用的结果(即使双方都“知道”它只能是 MyFoo 的一个实例)。

Note that there's nothing special about clone() and that any overridden method can have a covariant return - I used it as an example here as it's a standard method where this is often useful.

自 JDK 1.5发布以来,协变类型在 Java 中被引入。我会用一个简单的例子来解释它: When we override a function the function is allowed to make changes to it's behaviour这是你在大多数书中读到的,但是他们{作者}错过的是我们也可以改变返回类型。 我们可以改变返回类型,只要它可以被分配到返回类型的基本版本的方法。

因此,这种返回派生类型的特性称为 COVARIANT..。

重写的方法在返回类型上是否有所不同?

下面是另一个简单的例子:

Animal

public class Animal {


protected Food seekFood() {


return new Food();
}
}

Dog

public class Dog extends Animal {


@Override
protected Food seekFood() {


return new DogFood();
}
}

可以将 DogseekFood()方法的返回类型修改为 DogFood-Food的一个子类,如下所示:

@Override
protected DogFood seekFood() {


return new DogFood();
}

这完全是一个合法的重写,DogseekFood()方法的返回类型称为 covariant return type

协变的 Return 类型仅仅意味着返回自己的 Class 引用或其子类引用。

class Parent {
//it contain data member and data method
}


class Child extends Parent {
//it contain data member and data method
//covariant return
public Parent methodName() {
return new Parent();
or
return Child();
}


}
  • Java 中的协变返回值类型,允许缩小返回类型 of the overridden method.
  • 这个特性将有助于避免向下铸造 在客户端。它允许程序员无需编程 型式检查和下铸件。
  • 协变返回值类型总是 只对非基元返回类型有效。
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;
}
}

协变返回值类型指明返回类型可能与子类的方向相同

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

在 Java5之前,不可能重写任何方法 通过改变返回类型。但是现在,自从 Java5,

可以通过更改返回类型来重写方法 if subclass overrides any method 其返回类型为非原语的 但它将其返回类型更改为子类类型。

  • 它有助于避免混淆类层次结构中存在的类型强制转换 从而使代码具有可读性、可用性和可维护性。
  • 我们可以在重写时使用更具体的返回类型
    方法

  • 帮助防止返回时出现运行时 ClassCastException

reference: Www.geeksforgeeks.org

Before Java5, it was not possible to override any method by changing the return type. But now, since Java5, it is possible to override method by changing the return type if subclass overrides any method whose return type is Non-Primitive but it changes its return type to subclass type.

为了补充上述答案,可以在协变返回类型之间进行重写,约束条件是重写方法(子类方法)的返回类型应该是重写方法(超类方法)的返回类型的子类。从 Java5开始这是有效的。