Apa yang dimaksud dengan tipe pengembalian kovarian?

105

Apa yang dimaksud dengan tipe pengembalian kovarian di Jawa? Dalam pemrograman berorientasi objek secara umum?

Muncul
sumber
5
Posting blog ini ( blogs.oracle.com/sundararajan/entry/… ) menjelaskan, hanya menambah basis pengetahuan di sini.
Akhil Jain
@AkhilJain: Posting blog itu brilian dan sederhana. Ini adalah penjelasan-demi-contoh terbaik yang pernah saya lihat tentang bagaimana Java mendukung tipe kembalian kovarian.
kevinarpe
@kevinarpe terima kasih, saya senang ini membantu banyak orang.
Akhil Jain

Jawaban:

143

Pengembalian kovarian, berarti bahwa ketika seseorang menimpa sebuah metode, tipe kembalian dari metode penggantian diizinkan untuk menjadi subtipe dari tipe kembalian metode yang diganti.

Untuk memperjelas hal ini dengan sebuah contoh, kasus umum adalah Object.clone()- yang dideklarasikan untuk mengembalikan tipe Object. Anda dapat menimpanya di kelas Anda sendiri sebagai berikut:

public class MyFoo
{

   ...

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

Manfaatnya di sini adalah bahwa metode apa pun yang menyimpan referensi eksplisit ke objek MyFoo akan dapat memanggil clone()dan mengetahui (tanpa casting) bahwa nilai yang dikembalikan adalah turunannya MyFoo. Tanpa tipe kembalian kovarian, metode yang ditimpa di MyFoo harus dideklarasikan untuk dikembalikan Object- sehingga kode pemanggil harus secara eksplisit men-downcast hasil dari pemanggilan metode (meskipun kedua belah pihak "tahu" bahwa itu hanya dapat menjadi instance dari MyFoo ).

Perhatikan bahwa tidak ada yang istimewa tentang clone()dan bahwa metode yang ditimpa dapat memiliki pengembalian kovarian - Saya menggunakannya sebagai contoh di sini karena ini adalah metode standar yang sering kali berguna.

Andrzej Doyle
sumber
bukankah itu seharusnya terkait dengan List<Foo>dan List<FooBar>?
zinking
2
Itu jenis kovarian dalam arti yang lebih luas daripada hanya jenis kembalian kovarian yang ditanyakan di sini. Ini adalah prinsip dasar yang sama, meskipun - Anda dapat menganggap definisi tingkat atas clone()sebagai a Method<Void, Object>, dan menanyakan apakah yang lebih spesifik Method<Void, MyFoo>dapat ditetapkan ke jenis induk tersebut. Yang mana, jika dan hanya jika metode Java adalah kovarian dalam tipe kembaliannya.
Andrzej Doyle
38

Berikut contoh sederhana lainnya:

Animal kelas

public class Animal {

    protected Food seekFood() {

        return new Food();
    }
}

Dog kelas

public class Dog extends Animal {

    @Override
    protected Food seekFood() {

        return new DogFood();
    }
}

Ini mungkin untuk mengubah jenis kembalinya Dog's seekFood()metode untuk DogFood- subclass dari Food, seperti yang ditunjukkan di bawah ini:

@Override
protected DogFood seekFood() {

    return new DogFood();
}

Itu sempurna yang utama hukum, dan jenis kembalinya Dog's seekFood()metode yang dikenal sebagai tipe kembali kovarian .

Mohamed ALOUANE
sumber
8

Dari rilis JDK 1.5, jenis kovarian diperkenalkan di Jawa. dan saya akan menjelaskannya kepada Anda dengan kasus sederhana,: Saat kita mengganti fungsi, fungsi diizinkan untuk membuat perubahan pada perilakunya, itulah yang bisa Anda baca di sebagian besar buku, tetapi yang mereka {penulis} lewatkan adalah bahwa kita juga dapat mengubah tipe pengembalian. periksa tautan di bawah ini untuk klarifikasi kita dapat mengubah tipe pengembalian selama dapat ditugaskan untuk mengembalikan tipe versi dasar metode.

Jadi fitur pengembalian tipe turunan ini disebut COVARIANT ...

Bisakah metode yang diganti berbeda dalam tipe pengembalian?

PresidentPratik
sumber
7

tipe Pengembalian kovarian berarti mengembalikan referensi Kelas sendiri atau referensi kelas anaknya.

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

}
Dhiraj
sumber
1
Ini juga mencakup kasus di mana Parent.foo()mengembalikan tipe yang tidak terkaitA dan Child.foo()mengembalikan tipe yang Bberasal A.
Davis Herring
2

Untuk menambah jawaban di atas, penggantian dimungkinkan di antara tipe kembalian co-varian, dengan batasan bahwa tipe kembalian dari metode penggantian (metode subkelas) harus menjadi subkelas dari tipe kembalian dari metode yang diganti (metode superclass). Ini berlaku mulai dari Java 5 dan seterusnya.

Kehidupan Pai
sumber
1

Jenis kembalian kovarian menentukan bahwa jenis kembalian dapat bervariasi ke arah yang sama seperti subclass

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

Sebelum Java 5, tidak mungkin mengganti metode apa pun dengan mengubah tipe kembalian. Tapi sekarang, sejak Java5,

dimungkinkan untuk mengganti metode dengan mengubah tipe pengembalian jika subkelas menimpa metode apa pun yang tipe kembaliannya Non-Primitif tetapi mengubah tipe kembaliannya menjadi tipe subkelas.

Keshav Gera
sumber
1
  • Ini membantu menghindari tipe cast yang membingungkan yang ada dalam hierarki kelas dan dengan demikian membuat kode dapat dibaca, digunakan, dan dipelihara.
  • Kami memiliki kebebasan untuk memiliki tipe pengembalian yang lebih spesifik saat mengganti
    metode.

  • Bantuan dalam mencegah ClassCastExceptions run-time saat kembali

referensi: www.geeksforgeeks.org

Arun Raaj
sumber
0
  • Jenis pengembalian kovarian di java, memungkinkan mempersempit jenis pengembalian dari metode yang diganti.
  • Fitur ini akan membantu menghindari down casting di sisi klien. Hal ini memungkinkan pemrogram untuk memprogram tanpa perlu pengecekan jenis dan pengecoran ke bawah.
  • Tipe kembalian kovarian selalu berfungsi hanya untuk tipe kembalian non-primitif.
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();
    }
}

Contoh lainnya adalah dari 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;
    }
}
snr
sumber
0

Sebelum Java5, tidak mungkin mengganti metode apa pun dengan mengubah tipe kembalian. Tapi sekarang, sejak Java5, dimungkinkan untuk mengganti metode dengan mengubah tipe pengembalian jika subkelas mengganti metode apa pun yang tipe kembaliannya Non-Primitif tetapi mengubah tipe kembaliannya menjadi tipe subkelas.


sumber