Answers:
协变返回,意味着当一个方法重写时,允许重写方法的返回类型为重写方法返回类型的子类型。
为了举例说明,通常的情况是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()
,任何重写的方法都可以具有协变量返回值-我在这里以它为例,因为它是一种通常有用的标准方法。
List<Foo>
和和有关List<FooBar>
吗?
clone()
视为Method<Void, Object>
,并询问是否可以将更具体Method<Void, MyFoo>
的定义分配给该父类型。当且仅当Java方法的返回类型是协变的时才是。
这是另一个简单的例子:
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()
方法DogFood
-的一个子类Food
,如下所示:
@Override
protected DogFood seekFood() {
return new DogFood();
}
这完全是合法的覆盖,并且Dog
的seekFood()
方法的返回类型称为协变返回类型。
从JDK 1.5发行版开始,Java中引入了协变类型。我将用一个简单的例子向您解释:当我们重写一个函数时,允许该函数对其行为进行更改,这是您在大多数书籍中都会读到的,但是它们{作者}却错过了是我们也可以更改返回类型。检查下面的链接以弄清楚,我们可以更改返回类型,只要可以将其分配为方法的基本版本的返回类型即可。
因此,此返回派生类型的功能称为COVARIANT ...
协变量返回类型仅表示返回自己的类引用或其子类引用。
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();
}
}
Parent.foo()
返回不相关的类型A
并Child.foo()
返回B
从派生的类型的情况A
。
协变返回类型指定返回类型可以在与子类相同的方向上变化
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();
}
}
在Java 5之前,不可能通过更改返回类型来覆盖任何方法。但是现在,从Java5开始,
如果子类覆盖了返回类型为非原始的任何方法,但是将其返回类型更改为子类类型,则可以通过更改返回类型来覆盖方法。
覆盖
方法时,我们可以自由选择更具体的返回类型。
帮助防止返回时运行时ClassCastExceptions
参考:www.geeksforgeeks.org
- 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;
}
}
函数.java
@FunctionalInterface
public interface Function<T, R> {
........
........
........
........
static <T> Function<T, T> identity() {
return t -> t;
}
}
在Java5之前,无法通过更改返回类型来覆盖任何方法。但是现在,从Java5开始,如果子类覆盖了返回类型为Non-Primitive的任何方法,但是它将其返回类型更改为子类类型,则可以通过更改返回类型来覆盖方法。