题
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中进行了介绍。我会用一个简单的例子解释给你,当我们重写功能被允许进行更改的行为的函数的那就是你在大多数的书看,但什么他们{}作者错过的是,我们也可以改变返回类型。 查看以下链接进行澄清,只要它可以被分配到返回的方法的基础版本类型,我们可以改变返回值类型。
所以返回派生类型的此功能称为协变...
协变返回类型只是意味着返回自己的类引用或其子类引用。
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();
}
}
协变返回类型指明,返回类型也可以在相同的方向上的子类而异
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的,有可能通过如果子类覆盖其返回类型是非原始但它改变它的返回类型以子类型的任何方法改变返回类型重写方法。