2009-12-10 12 views
75

Co to jest typ kowariantny w języku Java? W ogóle programowanie obiektowe?Co to jest typ kowariantny?

+4

ten wpis na blogu (https://blogs.oracle.com/sundararajan/entry/covariant_return_types_in_java) wyjaśnia, po prostu dodając do bazy wiedzy tutaj. –

+0

@AkhilJain: Ten wpis na blogu jest genialny i prosty. Jest to najlepsze wyjaśnienie przykładowe, jakie kiedykolwiek widziałem, ponieważ Java obsługuje typy zmiennych kowariancyjnych. – kevinarpe

+0

@kevinarpe dzięki, cieszę się, że jest to pomocne dla tak wielu osób. –

Odpowiedz

107

Powrót kowariancji oznacza, że ​​w przypadku nadpisania metody, typ powrotu metody przesłaniania może być podtypem zwracanego typu metody nadpisanej.

Aby wyjaśnić to na przykładzie, częstym przypadkiem jest Object.clone() - który jest zadeklarowany jako zwracający typ Object. Można to zmienić w swojej własnej klasie, co następuje:

public class MyFoo 
{ 

    ... 

    // Note covariant return here, method does not just return Object 
    public MyFoo clone() 
    { 
     // Implementation 
    } 
} 

Korzyścią jest to, że każda metoda, która posiada wyraźne odniesienie do obiektu MyFoo będzie mógł powołać clone() i wiem (bez castingu), że wartość zwracana jest instancją MyFoo. Bez kowariantnych typów zwracania, przesłonięta metoda w MyFoo musiałaby zostać zadeklarowana, aby zwrócić Object - i dlatego kod wywołujący musiałby wyraźnie obniżyć wynik wywołania metody (nawet uważał, że obie strony "wiedzą", że może być tylko instancją MyFoo).

Zauważ, że nie ma nic szczególnego w przypadku clone() i że każda przesłonięta metoda może mieć współczynnik kowariantności - użyłem jej jako przykładu, ponieważ jest to standardowa metoda, w której jest to często przydatne.

+0

nie ma być powiązany z 'List ' i 'List '? – zinking

+2

Są to typy kowariantne w szerszym znaczeniu, a nie tylko typ kowariantny ** return ** tutaj zapytany. Jest to jednak ta sama podstawowa zasada - można pomyśleć o definicji "clone()" najwyższego poziomu jako o "Metodzie " i pytaniu, czy bardziej konkretna "Metoda " jest do tego przypisana typ macierzysty. Który to jest, jeśli i tylko wtedy, gdy metody Java są kowariantne w ich typie zwracanym. –

5

Od wersji JDK 1.5 typy kowariantne zostały wprowadzone w języku Java. i wyjaśnię ci to za pomocą prostego przykładu: Kiedy przejmujemy funkcję, funkcja może wprowadzać zmiany w jej zachowaniu. to właśnie czytasz w większości książek, ale co oni {autorzy} chybiają obecnie możemy zmienić typ zwrotu. Sprawdź poniżej link do wyjaśnienia, możemy zmienić typ zwrotu, o ile można go przypisać do typu zwrotu podstawowej wersji metody.

Więc ta cecha powrocie typów pochodnych nazywa kowariantna ...

Can overridden methods differ in return type?

27

Oto kolejny prosty przykład:

Animal klasa

public class Animal { 

    protected Food seekFood() { 

     return new Food(); 
    } 
} 

Dog klasa

public class Dog extends Animal { 

    @Override 
    protected Food seekFood() { 

     return new DogFood(); 
    } 
} 

Jest możliwe, aby zmienić typ Powrót DogseekFood() metody s do DogFood - podklasą Food, jak pokazano poniżej:

@Override 
protected DogFood seekFood() { 

    return new DogFood(); 
} 

To doskonale nadrzędnym prawnej i rodzaju powrót Dog” Metoda seekFood() jest znana pod nazwą covariant typ zwrotu.

3

covariant Typy powrotów oznaczają po prostu zwracanie własnego odwołania do klasy lub odniesienia do klasy potomnej. klasy nadrzędnej { // zawierać element danych i sposób danych }

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

} 
0
  • kowariantna typu powrót w Java umożliwia zawężenie typu zwrotnego metody zmiany.
  • Ta funkcja pomoże uniknąć rzucania w dół po stronie klienta. Umożliwia programistom programowanie bez potrzeby sprawdzania typu i odlewania w dół.
  • Typ kowariantności zawsze działa tylko w przypadku nieprazowych typów zwracanych.
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(); 
    } 
} 

Inny przykład pochodzi z Jawy,

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

kowariantna typ zwracany określa, że ​​zwracany typ może się zmieniać w tym samym kierunku co podklasy

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

Przed Java 5, to nie była jakaś metoda zmieniając typ zwracany możliwe nadpisanie. Ale teraz, ponieważ java5,

jest możliwe aby zastąpić metodę zmieniając typ zwracany jeśli podklasa zastępuje dowolną metodę którego powrót typ jest dla Primitive ale zmienia swój typ zwracany do podklasy rodzaju.