Saya bertanya-tanya apakah ada alasan khusus di Jawa untuk selalu menggunakan " extends
" daripada " implements
" untuk mendefinisikan batasan typeparameter.
Contoh:
public interface C {}
public class A<B implements C>{}
dilarang tapi
public class A<B extends C>{}
benar. Apa alasan untuk itu?
java
generics
syntax
design-choices
pengguna120623
sumber
sumber
implements
?" - "Karena hanya adaextends
".implements
tidak membawa sesuatu yang baru dan akan memperumit masalah lebih lanjut. Saya harap ini akan membantu Anda.Jawaban:
Tidak ada perbedaan semantik dalam bahasa kendala generik antara apakah suatu kelas 'mengimplementasikan' atau 'meluas'. Kemungkinan kendala adalah 'extends' dan 'super' - yaitu, apakah kelas ini dapat beroperasi dengan ditugaskan ke yang lain (meluas), atau apakah kelas ini dapat ditugaskan dari yang itu (super).
sumber
class Generic<RenderableT extends Renderable implements Draggable, Droppable, ...> { Generic(RenderableT toDrag) { x = (Draggable)toDrag; } }
Seseorang ingin mengkompilasi cek waktu.Jawabannya ada di sini :
Jadi begitulah, agak membingungkan, dan Oracle tahu itu.
sumber
getFoo(List<? super Foo> fooList)
HANYA berfungsi dengan kelas yang benar-benar diperluas oleh Fooclass Foo extends WildcardClass
. Dalam hal iniList<WildcardClass>
input yang dapat diterima. Namun setiap kelas yangFoo
mengimplementasikan tidak akan berhasilclass Foo implements NonWorkingWildcardClass
tidak berartiList<NonWorkingWildcardClass>
akan valid dalamgetFoo(List<? super Foo> fooList)
. Jelas!Mungkin karena untuk kedua belah pihak (B dan C) hanya tipe yang relevan, bukan implementasinya. Dalam contoh Anda
B bisa menjadi antarmuka juga. "extends" digunakan untuk mendefinisikan sub-antarmuka dan juga sub-kelas.
Saya biasanya menganggap 'Sub extends Super' sebagai ' Sub adalah seperti Super , tetapi dengan kemampuan tambahan', dan 'Clz mengimplementasikan Intf' karena ' Clz adalah realisasi dari Intf '. Dalam contoh Anda, ini akan cocok: B seperti C , tetapi dengan kemampuan tambahan. Kemampuan itu relevan di sini, bukan realisasinya.
sumber
Mungkin tipe dasar adalah parameter generik, jadi tipe aktual mungkin merupakan antarmuka kelas. Mempertimbangkan:
Juga dari antarmuka perspektif kode klien hampir tidak bisa dibedakan dari kelas, sedangkan untuk subtipe itu penting.
sumber
Berikut adalah contoh yang lebih terlibat tentang di mana ekstensi diizinkan dan mungkin apa yang Anda inginkan:
public class A<T1 extends Comparable<T1>>
sumber
Ini semacam arbitrer yang mana dari ketentuan yang digunakan. Bisa jadi sebaliknya. Mungkin para perancang bahasa menganggap "meluas" sebagai istilah yang paling mendasar, dan "mengimplementasikan" sebagai kasus khusus untuk antarmuka.
Tapi saya pikir
implements
akan lebih masuk akal. Saya pikir lebih banyak berkomunikasi bahwa tipe parameter tidak harus berada dalam hubungan pewarisan, mereka bisa dalam segala jenis hubungan subtipe.Java Glossary mengekspresikan pandangan yang serupa .
sumber
Kita terbiasa
dan sedikit penyimpangan dari aturan ini sangat membingungkan kami.
Sintaks tipe terikat didefinisikan sebagai
( JLS 12> 4.4. Jenis Variabel>
TypeBound
)Jika kami mengubahnya, kami pasti akan menambahkan
implements
kasus inidan berakhir dengan dua klausa yang diproses secara identik
( JLS 12> 4.3. Jenis dan Nilai Referensi>
ClassOrInterfaceType
)kecuali kita juga perlu diurus
implements
, yang akan memperumit masalah.Saya percaya itu adalah alasan utama mengapa
extends ClassOrInterfaceType
digunakan sebagai penggantiextends ClassType
danimplements InterfaceType
- untuk menjaga hal-hal sederhana dalam konsep rumit. Masalahnya adalah kita tidak memiliki kata yang tepat untuk membahas keduanyaextends
danimplements
dan kita pasti tidak ingin memperkenalkannya.<T is ClassTypeA>
<T is InterfaceTypeA>
Meskipun
extends
membawa beberapa kekacauan ketika berjalan seiring dengan antarmuka, itu adalah istilah yang lebih luas dan dapat digunakan untuk menggambarkan kedua kasus. Cobalah untuk menyesuaikan pikiran Anda dengan konsep memperluas jenis (tidakmemperluas kelas, tidakmengimplementasikan antarmuka). Anda membatasi parameter tipe oleh tipe lain dan tidak masalah apa tipe itu sebenarnya. Yang penting hanyalah batas atasnya dan supertipe .sumber
Bahkan, saat menggunakan generik pada antarmuka, kata kunci juga diperluas . Berikut ini contoh kode:
Ada 2 kelas yang mengimplementasikan antarmuka Ucapan:
Dan kode tes:
sumber