Siapa yang memperluas antarmuka? Dan mengapa?

20

AFAIK, extendskelas dan implementsantarmuka orangtua kelas saya . Tapi saya mengalami situasi, di mana saya tidak bisa menggunakan implements SomeInterface. Ini adalah deklarasi tipe generik. Sebagai contoh:

public interface CallsForGrow {...}

public class GrowingArrayList <T implements CallsForGrow>  // BAD, won't work!
                              extends ArrayList<T> 

implementsDilarang menggunakan di sini secara sintaksis. Saya pikir pertama, bahwa menggunakan antarmuka di dalam <> dilarang sama sekali, tetapi tidak. Mungkin saja, saya hanya perlu menggunakan extendssaja implements. Akibatnya, saya "memperluas" antarmuka. Ini contoh lain berfungsi:

public interface CallsForGrow {...}

public class GrowingArrayList <T extends CallsForGrow>  // this works!
                              extends ArrayList<T> 

Bagi saya itu tampaknya sebagai inkonsistensi sintaksis. Tapi mungkin saya tidak mengerti beberapa kemahiran Java 6? Apakah ada tempat lain di mana saya harus memperluas antarmuka? Haruskah antarmuka, yang saya maksudkan untuk diperluas, memiliki beberapa fitur khusus?

Gangnus
sumber

Jawaban:

25

Dalam kasus variabel tipe generik, kompiler tidak benar-benar peduli apakah Titu kelas, antarmuka, enum, atau anotasi. Yang perlu diperhatikan adalah bahwa itu adalah tipe dengan serangkaian sub dan super tipe tertentu.

Dan tidak ada alasan untuk menyulitkan sintaks hanya karena di satu tempat lain (di mana Anda benar-benar mengimplementasikan antarmuka) perbedaan antara kelas dan antarmuka relevan (misalnya jika Anda implementsebuah antarmuka, Anda perlu menerapkan semua metode yang ditetapkannya, tetapi Anda tidak perlu, jika Anda extendkelas (non-abstrak)).

Dengan asumsi sejenak bahwa Anda harus menulis di implementssini, maka Anda juga akan memerlukan sintaks terpisah untuk enumnilai - nilai (bukan hanya menulis <E extends Enum<E>>) dan anotasi (yang dapat Anda deklarasikan dengan mudah menggunakan <A extends Annotation>).

Satu-satunya tempat di mana Anda perlu menulis implementsadalah pada titik di mana Anda benar-benar mengimplementasikan antarmuka. Pada bahwa titik (dan titik saja) perbedaannya adalah penting, karena Anda harus menerapkan metode yang didefinisikan dalam antarmuka. Untuk semua orang, tidak masalah apakah yang diberikan Aadalah kelas dasar atau antarmuka yang diimplementasikan B: itu adalah tipe super dan hanya itu yang penting.

Perhatikan juga bahwa ada satu tempat lain yang Anda gunakan extendsdengan antarmuka:

interface A {
}

interface B extends A {
}

Pada titik ini implementsakan salah, karena B tidak diterapkan A .

Joachim Sauer
sumber
Jika kita akan menggunakan logika Anda, kita harus menggunakan 'meluas SomeInterface' selalu , tidak hanya di obat generik.
Gangnus
2
@ Gangnus: tidak, karena untuk implementor ada perbedaan nyata antara extendsdan implements, hanya ketika melihat masalah dari perspektif sistem tipe murni, bahwa tidak ada perbedaan.
Joachim Sauer
1
Maaf, saya tidak mengerti pikiran Anda. --1. Mengapa kita harus menggunakan "perspektif sistem tipe murni" dalam satu kasus dan tidak dalam yang lain? --2. Mengapa tuntutan sintaksis berubah di tempat-tempat yang berbeda ini? Bisakah Anda menjelaskannya? Dalam jawabannya, jika memungkinkan.
Gangnus
1
@ Gangnus: siapa bilang itu Tkelas? Tdapat mereferensikan tipe antarmuka atau enumtipe.
Joachim Sauer
1
berasal dari C #, seluruh diskusi ini konyol. kami menunjukkan tipe supertypes dengan :. dan di bawah selimut, sebuah antarmuka adalah dan selalu menjadi kelas abstrak dengan batasan hanya berisi abstractanggota virtual ( ) yang tidak diimplementasikan , sehingga memungkinkan pewarisan berganda. tidak ada perbedaan antara implementsdan extends. keduanya bisa diganti dengan kata yang sama ( extends) atau dengan simbol sewenang-wenang ( :) dan tidak ada yang akan hilang.
sara
5

Ketika Java 5, dan khususnya obat generik, pada awalnya dibuat tersedia untuk pengembang yang telah mendaftarkan minat, sintaksanya sangat berbeda. Alih-alih Set<? extends Foo>dan Set<? super Bar>itu telah Set<+Foo>dan Set<-Foo>. Namun, umpan baliknya adalah tidak jelas apakah +artinya lebih spesifik atau lebih luas (lebih banyak kelas) . Sun menanggapi umpan balik itu dengan mengubah sintaksis, tetapi dalam batasan tidak memperkenalkan kata kunci baru, yang akan menjadi masalah untuk kompatibilitas ke belakang.

Hasilnya adalah keduanya tidak alami. Seperti yang Anda amati, extendskelebihan beban untuk berbicara tentang kelas "memperluas" antarmuka, yang bukan bahasa yang digunakan dalam konteks lain; dan superkelebihan muatan berarti "adalah superclass", yang merupakan arah yang berlawanan dari hubungan yang sebelumnya diungkapkan oleh kata kunci, yaitu merujuk ke superclass.

Namun, dasar-dasar apa antarmuka tidak terpengaruh oleh perubahan ini, dan itu tidak memperkenalkan antarmuka khusus yang diperluas dengan cara baru.

Peter Taylor
sumber
+1. Saya melihat dan setuju. Tapi Joachim Sauer telah menemukan pemikiran keliru saya bahwa T harus kelas. Jadi, jawabannya adalah miliknya. Pemahaman Anda adalah satu (atau 2) tingkat lebih tinggi :-). Masalah saya lebih primitif. Terima kasih atas perkembangan saya.
Gangnus
2

Ada beberapa kelemahan dalam mengizinkan dan melarang sintaksis semacam itu, dan yang memperbolehkannya jauh lebih besar.

Pikirkan saja itu.

Pemisahan antarmuka dan implementasi adalah salah satu idiom pemrograman mendasar. Karena itu, sintaks yang memungkinkan untuk mengeja "antarmuka mengimplementasikan sesuatu" akan seburuk yang menggunakan tanda plus untuk menunjukkan multiplikasi operan.

agas
sumber
Baik. Jadi, saya benar-benar tidak mengerti sesuatu. Saya menganggapnya sangat mungkin. Tapi Anda belum menjelaskan masalahnya sama sekali, maaf. T adalah representasi kelas. Mengapa di satu tempat saya menggunakan ekstensi T dan di implementasi T lain?
Gangnus
@ Gangnus dalam contoh yang Anda berikan T merujuk ke tipe parameter yang belum tentu kelas - lihat apa yang sudah dikatakan Joachim kepada Anda . Mengizinkan alat untuk itu akan menyebabkan kekacauan yang sama yang saya sebutkan
nyamuk
Ya, saya sudah melihat komentarnya. Itu akan ditandai sebagai jawaban ketika dimasukkan ke dalam jawaban. Sampai Anda berdua mengucapkan terima kasih dan +1.
Gangnus
-1

Orang perlu memahami pemrograman berbasis antarmuka sebagai langkah selanjutnya sambil memahami suatu antarmuka. Ini memberitahu apa sebenarnya penggunaan antarmuka. Apa perannya dalam program Java (atau bahasa lainnya).

Deepak
sumber
2
Bagaimana jawaban Anda mengatasi masalah OP? Harap edit jawaban Anda agar lebih jelas.