[英]What is a covariant return type?
Java 中的协变返回类型是什么? 在面向对象的编程一般?
协变返回,意味着当一个方法重写时,重写方法的返回类型允许是被重写方法返回类型的子类型。
为了用一个例子来澄清这一点,一个常见的情况是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()
没有什么特别之处,并且任何被覆盖的方法都可以有一个协变返回——我在这里用它作为例子,因为它是一个标准方法,这通常很有用。
这是另一个简单的例子:
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 中引入了协变类型。 我会用一个简单的案例向你解释:当我们覆盖一个函数时,该函数被允许改变它的行为,这是你在大多数书中读到的,但他们{作者}错过了什么是我们也可以更改返回类型。 检查下面的链接以进行澄清,我们可以更改返回类型,只要它可以分配给方法的 Base 版本的返回类型。
所以这个返回派生类型的特性叫做 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();
}
}
为了补充上述答案,在协变返回类型之间可以进行覆盖,其约束是覆盖方法(子类方法)的返回类型应该是被覆盖方法(超类方法)的返回类型的子类。 这从 Java 5 开始有效。
协变返回类型指定返回类型可以在与子类相同的方向上变化
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,
一元运算符.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 开始,如果子类覆盖任何返回类型为非原始类型的方法,但它将其返回类型更改为子类类型,则可以通过更改返回类型来覆盖方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.