2009-12-10 105 views
75

什麼是Java中的協變返回類型?在一般的面向對象編程中?什麼是協變返回類型?

+4

此博客文章(https://blogs.oracle.com/sundararajan/entry/covariant_return_types_in_java)解釋說,只是在這裏添加知識庫。 – 2013-11-10 10:29:04

+0

@AkhilJain:那篇博文很出色,很簡單。這是我見過的關於Java如何支持協變返回類型的最佳解釋。 – kevinarpe 2016-10-11 09:58:00

+0

@kevinarpe謝謝,我很高興這對許多人有幫助。 – 2016-10-12 05:28:32

回答

107

協變返回,意味着當一個重寫方法時,重寫方法的返回類型被允許爲重寫方法的返回類型的子類型。

爲了說明這一點,一個常見的情況是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()沒有什麼特別之處,任何重寫的方法都可以有一個協變返回 - 我在這裏用它作爲示例,因爲它是一個常用的標準方法。

+0

是不是應該和'List '和'List '有關? – zinking 2016-06-12 08:53:24

+2

這是廣義上的協變類型,而不僅僅是在這裏被問到的協變**返回**類型。然而,它的基本原理是相同的 - 你可以將clone()的頂層定義看作是一個「Method 」,並詢問更具體的方法是否可以分配給父類型。它是什麼,當且僅當Java方法在返回類型中是協變的。 – 2016-06-14 11:58:32

5

從JDK 1.5發佈以來,協變類型在Java中引入。我會用一個簡單的例子向你解釋:當我們重寫一個函數時,該函數允許修改它的行爲這就是你在大多數書籍中閱讀的內容,但是他們(作者)錯過了什麼我們可以改變返回類型。 檢查下面的鏈接澄清我們可以改變返回類型,只要它可以分配給方法的基本版本的返回類型。

於是久違派生類型的這種功能稱爲協變...

Can overridden methods differ in return type?

27

這裏有另外一個簡單的例子:

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返回類型「方法被稱爲協變返回類型

3

協變返回類型僅僅意味着返回自己的類引用或其子類的引用。 類父 { //它包含數據構件和數據的方法 }

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

} 
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; 
    } 
} 
0

協變返回類型指明,返回類型也可以在相同的方向上的子類

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的,

可以通過,如果子類覆蓋任何方法 其返回類型爲非原始 但它改變了它的返回類型的子類類型改變的返回類型 重寫方法。