Hari ini, saya membaca beberapa artikel tentang Kovarian, Kontravarian (dan Selisih) di Jawa. Saya membaca artikel Wikipedia bahasa Inggris dan Jerman, serta beberapa postingan blog dan artikel lain dari IBM.
Tapi saya masih sedikit bingung tentang apa sebenarnya ini? Beberapa mengatakan ini tentang hubungan antara tipe dan subtipe, beberapa mengatakan ini tentang konversi tipe dan beberapa mengatakan ini digunakan untuk memutuskan apakah suatu metode diganti atau dibebani.
Jadi saya mencari penjelasan yang mudah dalam bahasa Inggris yang sederhana, yang menunjukkan kepada pemula apa itu Kovarian dan Kontravarian (dan Penyimpangan). Poin plus untuk contoh mudah.
Jawaban:
Semua yang di atas.
Intinya, istilah-istilah ini menjelaskan bagaimana hubungan subtipe dipengaruhi oleh transformasi tipe. Artinya, jika
A
danB
adalah tipe,f
adalah transformasi tipe, dan ≤ relasi subtipe (A ≤ B
artinya ituA
adalah subtipe dariB
), kita punyaf
adalah kovarian jikaA ≤ B
menyiratkan hal ituf(A) ≤ f(B)
f
bertentangan jikaA ≤ B
menyiratkan ituf(B) ≤ f(A)
f
adalah invarian jika tidak satu pun dari yang di atas berlakuMari pertimbangkan sebuah contoh. Biarkan
f(A) = List<A>
dimanaList
dideklarasikan olehApakah
f
kovarian, kontravarian, atau invarian? Kovarian akan berarti bahwa aList<String>
adalah subtipe dariList<Object>
, kontravarian bahwa aList<Object>
adalah subtipe dariList<String>
dan invarian yang tidak merupakan subtipe dari yang lain, yaituList<String>
danList<Object>
merupakan tipe yang tidak dapat diubah. Di Jawa, yang terakhir benar, kami mengatakan (agak informal) bahwa obat generik tidak berubah.Contoh lain. Biarkan
f(A) = A[]
. Apakahf
kovarian, kontravarian, atau invarian? Artinya, apakah String [] adalah subtipe dari Objek [], Objek [] adalah subtipe dari String [], atau bukan merupakan subtipe dari yang lain? (Jawaban: Di Jawa, array adalah kovarian)Ini masih agak abstrak. Untuk membuatnya lebih konkret, mari kita lihat operasi mana di Java yang didefinisikan dalam kaitannya dengan subtipe relasi. Contoh paling sederhana adalah penugasan. Pernyataan
akan mengkompilasi hanya jika
typeof(y) ≤ typeof(x)
. Artinya, kami baru saja mempelajari pernyataan itutidak akan dikompilasi di Jawa, tapi
akan.
Contoh lain di mana hubungan subtipe penting adalah ekspresi pemanggilan metode:
Secara informal, pernyataan ini dievaluasi dengan menetapkan nilai
a
ke parameter pertama metode, kemudian menjalankan isi metode, dan kemudian menetapkan nilai kembali metode keresult
. Seperti tugas sederhana pada contoh terakhir, "sisi kanan" harus merupakan subtipe dari "sisi kiri", yaitu pernyataan ini hanya dapat valid jikatypeof(a) ≤ typeof(parameter(method))
danreturntype(method) ≤ typeof(result)
. Artinya, jika metode dideklarasikan oleh:tidak ada ekspresi berikut yang akan dikompilasi:
tapi
akan.
Contoh lain di mana subtyping penting. Mempertimbangkan:
dimana
Secara informal, runtime akan menulis ulang ini menjadi:
Untuk baris yang ditandai untuk dikompilasi, parameter metode dari metode penggantian harus supertipe dari parameter metode dari metode yang diganti, dan tipe kembalian adalah subtipe dari metode yang diganti. Secara formal,
f(A) = parametertype(method asdeclaredin(A))
setidaknya harus kontravarian, dan jikaf(A) = returntype(method asdeclaredin(A))
setidaknya harus kovarian.Perhatikan "setidaknya" di atas. Itu adalah persyaratan minimum yang akan diberlakukan oleh bahasa pemrograman berorientasi objek aman jenis statis yang masuk akal, tetapi bahasa pemrograman mungkin memilih untuk lebih ketat. Dalam kasus Java 1.4, tipe parameter dan tipe kembalian metode harus identik (kecuali untuk penghapusan tipe) saat mengganti metode, yaitu
parametertype(method asdeclaredin(A)) = parametertype(method asdeclaredin(B))
saat mengganti. Sejak Java 1.5, jenis kembalian kovarian diizinkan saat mengganti, yaitu berikut ini akan dikompilasi di Java 1.5, tetapi tidak di Java 1.4:Saya harap saya menutupi semuanya - atau lebih tepatnya, menggores permukaan. Tetap saja saya berharap ini akan membantu untuk memahami konsep varian tipe yang abstrak, tetapi penting.
sumber
A ≤ B
. Notasi itu membuat segala sesuatunya jauh lebih sederhana dan bermakna. Bacaan yang bagus ...Mengambil sistem tipe java, dan kemudian kelas:
Setiap objek dari beberapa tipe T dapat diganti dengan objek subtipe T.
TYPE VARIANCE - METODE KELAS MEMILIKI KONSEKUENSI BERIKUT
Dapat dilihat bahwa:
Sekarang co- dan contra- berhubungan dengan B menjadi subtipe dari A. Pengetikan yang lebih kuat berikut dapat diperkenalkan dengan pengetahuan yang lebih spesifik. Di subtipe.
Kovarian (tersedia di Java) berguna, untuk mengatakan bahwa seseorang mengembalikan hasil yang lebih spesifik dalam subtipe; terutama terlihat ketika A = T dan B = S. Kontradiksi mengatakan Anda siap untuk menangani argumen yang lebih umum.
sumber
Varians adalah tentang hubungan antar kelas dengan parameter generik yang berbeda. Hubungan mereka adalah alasan mengapa kami dapat memilih mereka.
Varians Co dan Contra adalah hal yang cukup logis. Sistem tipe bahasa memaksa kita untuk mendukung logika kehidupan nyata. Mudah dipahami dengan contoh.
Kovarian
Misalnya Anda ingin membeli sebuah bunga dan Anda memiliki dua toko bunga di kota Anda: toko mawar dan toko bunga aster.
Jika Anda bertanya kepada seseorang "di mana toko bunga?" dan seseorang memberitahu Anda di mana toko mawar, apakah tidak apa-apa? ya, karena mawar itu bunga, kalau mau beli bunga bisa beli mawar. Hal yang sama berlaku jika seseorang menjawab Anda dengan alamat toko bunga aster. Ini adalah contoh kovarians : Anda diizinkan untuk melakukan cast
A<C>
keA<B>
, di manaC
subkelasnyaB
, jikaA
menghasilkan nilai-nilai umum (dikembalikan sebagai hasil dari fungsi). Kovarian adalah tentang produsen.Jenis:
Pertanyaannya adalah "dimana toko bunga itu?", Jawabannya "toko mawar disana":
Kontravarian
Misalnya Anda ingin memberikan bunga kepada pacar Anda. Jika pacar Anda menyukai bunga apa pun, dapatkah Anda menganggapnya sebagai orang yang menyukai mawar, atau sebagai orang yang menyukai bunga aster? ya, karena jika dia menyukai bunga apa pun, dia akan menyukai mawar dan bunga aster. Ini adalah contoh kontradiksi : Anda diizinkan untuk melakukan cast
A<B>
keA<C>
, di manaC
subkelasnyaB
, jikaA
menggunakan nilai generik. Kontradiksi adalah tentang konsumen.Jenis:
Anda sedang mempertimbangkan pacar Anda yang menyukai bunga apa pun sebagai seseorang yang menyukai mawar, dan memberinya mawar:
Anda dapat menemukan lebih banyak di Sumber .
sumber