什么是协变回报类型?

时间:2009-12-10 17:23:13

标签: java oop covariance

Java中的协变返回类型是什么?在面向对象的编程中一般吗?

9 个答案:

答案 0 :(得分:129)

协变返回,意味着当一个覆盖方法时,覆盖方法的返回类型被允许为被覆盖方法的返回类型的子类型。

为了用一个例子来澄清这一点,一个常见的例子是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的一个实例。)

请注意,clone()并没有什么特别的,任何被覆盖的方法都可以有一个协变返回 - 我在这里用它作为一个例子,因为它是一个标准的方法,这通常很有用。

答案 1 :(得分:33)

这是另一个简单的例子:

Animal上课

public class Animal {

    protected Food seekFood() {

        return new Food();
    }
}

Dog上课

public class Dog extends Animal {

    @Override
    protected Food seekFood() {

        return new DogFood();
    }
}

可以将Dog的{​​{1}}方法的返回类型修改为seekFood() - DogFood的子类,如下所示:

Food

这完全是合法的覆盖,@Override protected DogFood seekFood() { return new DogFood(); } 的{​​{1}}方法的返回类型称为协变返回类型

答案 2 :(得分:6)

从JDK 1.5的发布版本开始,Java中引入了协变类型。我会用一个简单的例子向你解释一下:当我们覆盖一个函数时,该函数可以改变它的行为这是你在大多数书中读到的内容,但是他们{作者}错过的是我们也可以改变返回类型。 检查下面的链接以便澄清我们可以更改返回类型,只要它可以分配给方法的基本版本的返回类型。

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

Can overridden methods differ in return type?

答案 3 :(得分:6)

协变返回类型只是表示返回自己的类引用或其子类引用。

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

}

答案 4 :(得分:1)

协变返回类型指定返回类型可以在与子类

相同的方向上变化
requestPayload

在Java 5之前,无法覆盖任何方法 通过更改返回类型。但是现在,自Java5以来,

可以通过更改返回类型来覆盖方法 if子类重写任何方法 其返回类型为Non-Primitive 但它将其返回类型更改为子类类型。

答案 5 :(得分:1)

  • 有助于避免混淆类层次结构中存在的类型转换 从而使代码可读,可用和可维护。
  • 在覆盖时,我们可以获得更多特定的返回类型 方法

  • 帮助阻止返回时的运行时ClassCastExceptions

参考: www.geeksforgeeks.org

答案 6 :(得分:1)

要添加到上述答案中,可以在协变量返回类型之间进行覆盖,但有一个约束,即重写方法(子类方法)的返回类型应为重写方法(超类方法)的返回类型的子类。 )。从Java 5开始有效。

答案 7 :(得分:0)

  
      
  • java中的协变返回类型允许缩小返回类型   被覆盖的方法。
  •   
  • 此功能有助于避免向下投射   在客户端。它允许程序员无需编程   类型检查和向下铸造。
  •   
  • 始终是协变返回类型   仅适用于非原始返回类型。
  •   
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;
    }
}

答案 8 :(得分:0)

在Java5之前,无法通过更改返回类型来覆盖任何方法。但是现在,从Java5开始,如果子类覆盖了返回类型为非原始的任何方法,但是它将返回类型更改为子类类型,则可以通过更改返回类型来覆盖方法。