Dari pemahaman saya jika Anda mengimplementasikan antarmuka di java, metode yang ditentukan dalam antarmuka itu harus digunakan oleh sub kelas yang mengimplementasikan antarmuka tersebut.
Saya perhatikan bahwa di beberapa antarmuka seperti antarmuka Collection ada metode yang dikomentari sebagai opsional, tetapi apa sebenarnya artinya ini? Itu membuat saya sedikit bingung karena saya pikir semua metode yang ditentukan dalam antarmuka akan diperlukan?
Jawaban:
Sepertinya ada banyak kebingungan dalam jawaban di sini.
Bahasa Java mengharuskan setiap metode dalam sebuah antarmuka diimplementasikan oleh setiap implementasi antarmuka itu. Titik. Tidak ada pengecualian untuk aturan ini. Mengatakan "Koleksi adalah pengecualian" menunjukkan pemahaman yang sangat kabur tentang apa yang sebenarnya terjadi di sini.
Penting untuk disadari bahwa ada dua tingkat penyesuaian pada sebuah antarmuka:
Apa yang bisa diperiksa oleh bahasa Java. Intinya adalah: apakah ada beberapa implementasi untuk masing-masing metode?
Benar-benar memenuhi kontrak. Artinya, apakah implementasi melakukan apa yang dikatakan oleh dokumentasi di antarmuka?
Antarmuka yang ditulis dengan baik akan mencakup dokumentasi yang menjelaskan dengan tepat apa yang diharapkan dari implementasi. Kompiler Anda tidak dapat memeriksa ini untuk Anda. Anda perlu membaca dokumen, dan melakukan apa yang mereka katakan. Jika Anda tidak melakukan apa yang kontrak katakan maka Anda akan memiliki implementasi antarmuka sejauh menyangkut kompilator , tetapi itu akan menjadi implementasi yang rusak / tidak valid.
Ketika mendesain Collections API Joshua Bloch memutuskan bahwa alih-alih memiliki antarmuka yang sangat halus untuk membedakan antara varian koleksi yang berbeda (misalnya: dapat dibaca, ditulis, akses acak, dll.) Dia hanya memiliki seperangkat antarmuka yang sangat kasar, terutama
Collection
,List
,Set
danMap
, dan kemudian mendokumentasikan operasi tertentu sebagai "opsional". Ini untuk menghindari ledakan kombinatorial yang akan dihasilkan dari antarmuka berbutir halus. Dari FAQ Desain Java Collections API :Ketika metode dalam Collections API didokumentasikan sebagai "operasi opsional", itu tidak berarti bahwa Anda dapat membiarkan penerapan metode dalam implementasi, juga tidak berarti Anda dapat menggunakan tubuh metode kosong (untuk satu hal, banyak dari mereka perlu mengembalikan hasil). Sebaliknya, itu berarti bahwa pilihan implementasi yang valid (yang masih sesuai dengan kontrak) adalah melempar
UnsupportedOperationException
.Perhatikan bahwa karena
UnsupportedOperationException
adalah,RuntimeException
Anda dapat membuangnya dari implementasi metode apa pun, sejauh menyangkut kompilator. Misalnya, Anda bisa membuangnya dari implementasiCollection.size()
. Namun, penerapan seperti itu akan melanggar kontrak karena di dalam dokumentasiCollection.size()
tidak disebutkan bahwa hal itu diizinkan.Selain: Pendekatan yang digunakan oleh API Koleksi Java agak kontroversial (mungkin sekarang kurang dari saat pertama kali diperkenalkan). Di dunia yang sempurna, antarmuka tidak akan memiliki operasi opsional, dan antarmuka berbutir halus akan digunakan. Masalahnya adalah bahwa Java tidak mendukung tipe struktural atau tipe persimpangan yang disimpulkan, itulah sebabnya mencoba melakukan sesuatu dengan "cara yang benar" akhirnya menjadi sangat berat dalam kasus pengumpulan.
sumber
There are no exceptions to this rule
. Ingin tahu mengapa jawaban ini tidak ditandai sebagai diterima. Yang lain baik tetapi Anda telah memberi lebih dari cukup.Foo
yang tidak diimplementasikanRunnable
dengan metode publikvoid run()
. Sekarang buat kelasBar
ituextends Foo
danimplements Runnable
tanpa berlebihanrun
. Itu masih menerapkan metode tersebut, meskipun secara tidak langsung. Demikian juga, implementasi metode default masih merupakan implementasi.remove
diberikan implementasi default. Jika Anda tidak mengimplementasikannya, maka kelas Anda akan mendapatkan implementasi default. Dua metode lain yang Anda sebutkan tidak memiliki implementasi default.Untuk mengkompilasi kelas pelaksana (non abstrak) untuk sebuah antarmuka - semua metode harus diimplementasikan.
Namun , jika kita memikirkan metode yang implementasinya adalah pengecualian sederhana sebagai 'tidak diimplementasikan' (seperti beberapa metode dalam
Collection
antarmuka), makaCollection
antarmuka adalah pengecualian dalam kasus ini, bukan kasus biasa. Biasanya , mengimplementasikan kelas harus (dan akan) mengimplementasikan semua metode.The "opsional" dalam koleksi berarti bahwa kelas pelaksana tidak harus 'mengimplementasikan' (menurut terminologi di atas) itu, dan itu hanya akan melempar
NotSupportedException
).Contoh yang baik -
add()
metode untuk koleksi yang tidak berubah - beton hanya akan mengimplementasikan metode yang tidak melakukan apa pun selain melemparNotSupportedException
Dalam kasus
Collection
ini dilakukan untuk mencegah pohon warisan yang berantakan, yang akan membuat pemrogram sengsara - tetapi untuk kebanyakan kasus, paradigma ini tidak disarankan, dan harus dihindari jika memungkinkan.Memperbarui:
Pada java 8, metode default diperkenalkan.
Artinya, sebuah antarmuka dapat mendefinisikan sebuah metode - termasuk implementasinya.
Ini ditambahkan untuk memungkinkan penambahan fungsionalitas ke antarmuka, sambil tetap mendukung kompatibilitas mundur untuk potongan kode yang tidak memerlukan fungsionalitas baru.
Perhatikan bahwa metode ini masih diterapkan oleh semua kelas yang mendeklarasikannya, tetapi menggunakan definisi antarmuka.
sumber
Antarmuka di Java hanya mendeklarasikan kontrak untuk mengimplementasikan kelas. Semua metode dalam antarmuka itu harus diimplementasikan, tetapi kelas pelaksana bebas membiarkannya tidak diimplementasikan, yaitu, kosong. Sebagai contoh yang dibuat-buat,
Sekarang saya
doSomethingElse()
tidak menerapkannya, membiarkannya gratis untuk diterapkan oleh subclass saya. Itu opsional.Namun, jika Anda berbicara tentang antarmuka Collection, seperti yang dikatakan orang lain, itu adalah pengecualian. Jika metode tertentu dibiarkan tidak diterapkan dan Anda memanggilnya, metode tersebut dapat menimbulkan
UnsupportedOperationException
pengecualian.sumber
Metode opsional dalam antarmuka Koleksi berarti bahwa penerapan metode diizinkan untuk menampilkan pengecualian, tetapi tetap harus diterapkan. Seperti ditentukan dalam dokumen :
sumber
new Runnable ( ) { @ Override public void run ( ) { throw new UnsupportedOperationException ( ) ; } }
;add((T)null)
mungkin valid dalam satu kasus tetapi tidak dalam kasus lain. Artinya, ini berbicara tentang pengecualian / perilaku opsional dan untuk argumen ("pembatasan elemen" ... "elemen tidak memenuhi syarat" ... "pengecualian ditandai sebagai opsional") dan tidak membahas metode opsional .Semua metode harus diimplementasikan agar kode dapat dikompilasi, (selain dari yang memiliki
default
implementasi di Java 8+), tetapi implementasinya tidak harus melakukan sesuatu yang berguna secara fungsional. Secara khusus, itu:UnsupportedOperationException
(atau serupa)Pendekatan terakhir sering diambil dalam kelas koleksi - semua metode masih diimplementasikan, tetapi beberapa mungkin memunculkan pengecualian jika dipanggil saat runtime.
sumber
Nyatanya, saya terinspirasi oleh SurfaceView.Callback2. Saya pikir ini adalah cara resmi
Jika kelas Anda tidak perlu mengimplementasikan metode opsional, cukup "implementasikan Callback". Jika kelas Anda perlu mengimplementasikan metode opsional, cukup "implementasikan CallbackExtended".
Maaf untuk bahasa Inggris yang buruk.
sumber
Di Java 8 dan yang lebih baru, jawaban atas pertanyaan ini masih valid tetapi sekarang lebih bernuansa.
Pertama, pernyataan dari jawaban yang diterima ini tetap benar:
Lantas, apa nuansa baru di Java 8 ini? Saat berbicara tentang "Metode Opsional", salah satu dari berikut ini sekarang tepat:
1. Metode yang implementasinya bersifat opsional secara kontrak
"Pernyataan ketiga" mengatakan bahwa metode antarmuka abstrak harus selalu diterapkan dan ini tetap berlaku di Java 8+. Namun, seperti dalam Java Collections Framework, beberapa metode antarmuka abstrak dapat dijelaskan sebagai "opsional" dalam kontrak.
Dalam hal ini, penulis yang mengimplementasikan antarmuka dapat memilih untuk tidak mengimplementasikan metode tersebut. Akan tetapi, compiler akan menuntut sebuah implementasi, dan karenanya penulis menggunakan kode ini untuk setiap metode opsional yang tidak diperlukan dalam kelas implementasi tertentu:
Di Java 7 dan sebelumnya, ini benar-benar satu-satunya jenis "metode opsional" yang ada, yaitu metode yang, jika tidak diterapkan, akan menampilkan UnsupportedOperationException. Perilaku ini harus ditentukan oleh kontrak antarmuka (mis. Metode antarmuka opsional dari Java Collections Framework).
2. Metode default yang penerapan ulangnya adalah opsional
Java 8 memperkenalkan konsep metode default . Ini adalah metode yang implementasinya dapat dan disediakan oleh definisi antarmuka itu sendiri. Secara umum hanya mungkin untuk menyediakan metode default ketika tubuh metode dapat ditulis menggunakan metode antarmuka lain (yaitu, "primitif"), dan bila
this
dapat berarti "objek ini yang kelasnya telah mengimplementasikan antarmuka ini".Metode default harus memenuhi kontrak antarmuka (seperti implementasi metode antarmuka lainnya harus). Oleh karena itu, menentukan implementasi metode antarmuka dalam kelas pelaksana adalah kebijaksanaan penulis (selama perilakunya sesuai dengan tujuannya).
Di lingkungan baru ini, Java Collections Framework dapat ditulis ulang sebagai:
Dengan cara ini, metode "opsional"
add()
memiliki perilaku default yaitu melontarkan UnsupportedOperationException jika kelas implementasi tidak menyediakan perilaku baru sendiri, yang persis seperti yang Anda inginkan terjadi dan yang sesuai dengan kontrak untuk List. Jika seorang penulis sedang menulis sebuah kelas yang tidak memperbolehkan elemen baru untuk ditambahkan ke implementasi List, implementasi dariadd()
adalah opsional karena perilaku default persis seperti yang dibutuhkan.Dalam kasus ini, "pernyataan ketiga" di atas masih berlaku, karena metode tersebut telah diterapkan di antarmuka itu sendiri.
3. Metode yang mengembalikan
Optional
hasilJenis baru terakhir dari metode opsional hanyalah metode yang mengembalikan file
Optional
. TheOptional
kelas menyediakan cara yang jelas lebih berorientasi objek berurusan dengannull
hasil.Dalam gaya pemrograman yang lancar, seperti jenis yang biasa terlihat saat membuat kode dengan Java Streams API baru, hasil nol pada titik mana pun menyebabkan program mogok dengan NullPointerException. The
Optional
kelas menyediakan mekanisme untuk mengembalikan hasil nol untuk kode klien dengan cara yang memungkinkan gaya fasih tanpa menyebabkan kode klien untuk kecelakaan.sumber
Jika kita menelusuri kode AbstractCollection.java di grepCode yang merupakan kelas leluhur untuk semua implementasi koleksi, ini akan membantu kita memahami arti dari metode opsional. Berikut adalah kode untuk metode add (e) di kelas AbstractCollection. menambahkan (e) metode adalah opsional menurut antarmuka koleksi
Metode opsional berarti sudah diterapkan di kelas leluhur dan melontarkan UnsupportedOperationException saat pemanggilan. Jika kami ingin membuat koleksi kami dapat dimodifikasi maka kami harus mengganti metode opsional dalam antarmuka koleksi.
sumber
Nah, topik ini telah disesuaikan dengan ... ya .. tapi pikirkan, satu jawaban hilang. Saya berbicara tentang "Metode Default" antarmuka. Misalnya, bayangkan Anda akan memiliki kelas untuk menutup apa pun (seperti destruktor atau sesuatu). Katakanlah itu harus memiliki 3 metode. Sebut saja mereka "doFirst ()", "doLast ()" dan "onClose ()".
Jadi kita katakan kita ingin objek apa pun dari tipe itu setidaknya mewujudkan "onClose ()", tetapi yang lain adalah opsional.
Anda dapat menyadari itu, dengan menggunakan "Metode Default" antarmuka. Saya tahu, ini sebagian besar waktu akan meniadakan alasan antarmuka, tetapi jika Anda merancang kerangka kerja, ini dapat berguna.
Jadi jika ingin mewujudkannya seperti ini, maka akan terlihat seperti berikut ini
Apa yang sekarang akan terjadi, jika Anda misalnya mengimplementasikannya dalam kelas yang disebut "Test", compiler akan baik-baik saja dengan yang berikut:
dengan Output:
atau
dengan keluaran:
Semua kombinasi dimungkinkan. Apa pun dengan "default" dapat diterapkan, tetapi tidak boleh, namun apa pun yang tidak harus diterapkan.
Semoga tidak sepenuhnya salah yang sekarang saya jawab.
Semoga harimu menyenangkan semuanya!
[edit1]: Harap diperhatikan: Ini hanya bekerja di Java 8.
sumber
Saya sedang mencari cara untuk mengimplementasikan antarmuka panggilan balik, jadi menerapkan metode opsional diperlukan karena saya tidak ingin menerapkan setiap metode untuk setiap panggilan balik.
Jadi, alih-alih menggunakan antarmuka, saya menggunakan kelas dengan implementasi kosong seperti:
Dan Anda dapat mengatur variabel anggota CallBack seperti ini,
lalu sebut saja seperti ini.
Dengan cara ini, Anda tidak perlu khawatir tentang mengimplementasikan setiap metode per panggilan balik, tetapi hanya mengganti yang Anda butuhkan.
sumber
Meskipun tidak menjawab pertanyaan OP, perlu dicatat bahwa pada Java 8 menambahkan metode default ke antarmuka sebenarnya bisa dilakukan . Kata
default
kunci yang ditempatkan di tanda tangan metode antarmuka akan menghasilkan kelas yang memiliki opsi untuk mengganti metode, tetapi tidak mengharuskannya.sumber
Tutorial Koleksi Java Oracle:
sumber