Java 8 memungkinkan untuk penerapan metode standar dalam antarmuka yang disebut Metode Standar .
Saya bingung antara kapan saya akan menggunakan itu interface default method
, bukannya abstract class
(dengan abstract method(s)
).
Jadi kapan antarmuka dengan metode standar digunakan dan kapan kelas abstrak (dengan metode abstrak) digunakan? Apakah kelas abstrak masih berguna dalam skenario itu?
java
interface
java-8
abstract-class
default-method
Narendra Pathai
sumber
sumber
Jawaban:
Ada jauh lebih banyak untuk kelas abstrak daripada implementasi metode default (seperti negara pribadi), tetapi pada Java 8, setiap kali Anda memiliki pilihan baik, Anda harus pergi dengan metode defender (alias.
default
) Di antarmuka.Kendala pada metode default adalah bahwa hal itu dapat diimplementasikan hanya dalam hal panggilan ke metode antarmuka lainnya, tanpa referensi ke keadaan implementasi tertentu. Jadi use case utama adalah metode tingkat tinggi dan kenyamanan.
Hal yang baik tentang fitur baru ini adalah bahwa, di mana sebelum Anda dipaksa untuk menggunakan kelas abstrak untuk metode kenyamanan, sehingga membatasi implementor ke warisan tunggal, sekarang Anda dapat memiliki desain yang benar-benar bersih hanya dengan antarmuka dan minimum implementasi upaya dipaksakan pada programmer.
Motivasi asli untuk memperkenalkan
default
metode ke Java 8 adalah keinginan untuk memperluas antarmuka Collections Framework dengan metode yang berorientasi lambda tanpa merusak implementasi yang ada. Meskipun ini lebih relevan bagi penulis perpustakaan umum, Anda mungkin menemukan fitur yang sama berguna dalam proyek Anda juga. Anda punya satu tempat terpusat tempat untuk menambah kenyamanan baru dan Anda tidak harus bergantung pada bagaimana sisa dari hirarki jenis terlihat.sumber
Ada beberapa perbedaan teknis. Kelas abstrak masih bisa berbuat lebih banyak dibandingkan dengan antarmuka Java 8:
Secara konseptual, tujuan utama metode bek adalah kompatibilitas mundur setelah pengenalan fitur-fitur baru (sebagai fungsi lambda) di Jawa 8.
sumber
public static final
bidang antarmuka sebagai "negara". Bagian inistatic
berarti bahwa mereka sama sekali tidak terkait dengan contoh tertentu. Mereka ditugaskan pada instantiation kelas , yang tidak sama dengan setelah pembuatan instance .Ini sedang dijelaskan dalam artikel ini . Pikirkan tentang
forEach
Koleksi.sumber
AbstractList::forEach
melemparUnsupportedOperationException
.Keduanya sangat berbeda:
Metode default adalah menambahkan fungsionalitas eksternal ke kelas yang ada tanpa mengubah statusnya.
Dan kelas abstrak adalah jenis warisan normal , mereka adalah kelas normal yang dimaksudkan untuk diperpanjang.
sumber
Seperti yang dijelaskan dalam artikel ini ,
Kelas abstrak versus antarmuka di Java 8
sumber
Mengenai kueri Anda tentang
dokumentasi java memberikan jawaban sempurna.
Kelas Abstrak Dibandingkan dengan Antarmuka:
Gunakan kasus untuk masing-masing dari mereka telah dijelaskan di bawah posting SE:
Apa perbedaan antara antarmuka dan kelas abstrak?
Iya. Mereka masih berguna. Mereka dapat berisi metode dan atribut non-statis, non-final ( dilindungi, pribadi selain untuk publik ), yang tidak mungkin bahkan dengan antarmuka Java-8.
sumber
Setiap kali kita memiliki pilihan antara kelas abstrak dan antarmuka, kita harus selalu (hampir) lebih memilih metode default (juga dikenal sebagai ekstensi defender atau virtual).
Collection and AbstractCollection
. Sekarang kita harus mengimplementasikan metode dalam antarmuka itu sendiri untuk menyediakan fungsionalitas default. Kelas-kelas yang mengimplementasikan antarmuka memiliki pilihan untuk mengganti metode atau mewarisi implementasi default.Penggunaan penting lain dari metode standar adalah
interface evolution
. Misalkan saya memiliki Ball kelas sebagai:public class Ball implements Collection { ... }
Sekarang di Java 8 fitur baru di stream diperkenalkan. Kita bisa mendapatkan aliran dengan menggunakan
stream
metode yang ditambahkan ke antarmuka. Jikastream
bukan metode default semua implementasi untukCollection
antarmuka akan rusak karena mereka tidak akan menerapkan metode baru ini. Menambahkan metode non-default ke antarmuka tidaksource-compatible
.Tetapi misalkan kita tidak mengkompilasi ulang kelas dan menggunakan file jar lama yang berisi kelas ini
Ball
. Kelas akan memuat dengan baik tanpa metode yang hilang ini, instance dapat dibuat dan tampaknya semuanya berfungsi dengan baik. TETAPI jika program memanggilstream
metode yangBall
akan kita dapatkanAbstractMethodError
. Jadi membuat metode standar menyelesaikan kedua masalah tersebut.sumber
Metode default di antarmuka Java memungkinkan evolusi antarmuka .
Diberikan antarmuka yang ada, jika Anda ingin menambahkan metode tanpa melanggar kompatibilitas biner dengan versi antarmuka yang lebih lama, Anda memiliki dua opsi: menambahkan metode default atau statis. Memang, setiap metode abstrak yang ditambahkan ke antarmuka harus dimasuki oleh kelas atau antarmuka yang mengimplementasikan antarmuka ini.
Metode statis adalah unik untuk suatu kelas. Metode default unik untuk turunan kelas.
Jika Anda menambahkan metode default ke antarmuka yang ada, kelas dan antarmuka yang mengimplementasikan antarmuka ini tidak perlu mengimplementasikannya. Mereka bisa
Lebih banyak tentang topik di sini .
sumber
Meskipun ini adalah pertanyaan lama, izinkan saya memberi masukan untuknya juga.
kelas abstrak: Di dalam kelas abstrak kita bisa mendeklarasikan variabel instan, yang diperlukan untuk kelas anak
Antarmuka: Antarmuka di dalam setiap variabel selalu statis publik dan final, kami tidak dapat mendeklarasikan variabel instan
kelas abstrak: kelas abstrak dapat berbicara tentang keadaan objek
Antarmuka: Antarmuka tidak pernah dapat berbicara tentang keadaan objek
kelas abstrak: Di dalam kelas Abstrak kita dapat mendeklarasikan konstruktor
Antarmuka: Di dalam antarmuka kita tidak dapat mendeklarasikan konstruktor karena tujuan
konstruktor adalah untuk menginisialisasi variabel instan. Jadi apa perlunya konstruktor di sana jika kita tidak dapat memiliki variabel instan dalam antarmuka .
kelas abstrak: Di dalam kelas abstrak kita dapat mendeklarasikan instance dan blok statis
Antarmuka: Antarmuka tidak dapat memiliki instance dan blok statis.
kelas abstrak: kelas abstrak tidak dapat merujuk ekspresi lambda
Antarmuka: Antarmuka dengan metode abstrak tunggal dapat merujuk ekspresi lambda
kelas abstrak : Di dalam kelas abstrak kita dapat mengganti metode OBJECT CLASS
Antarmuka: Kami tidak dapat mengganti metode OBJECT CLASS di dalam antarmuka.
Saya akan mengakhiri dengan catatan bahwa:
Konsep metode default / konsep metode statis dalam antarmuka datang hanya untuk menyelamatkan kelas implementasi tetapi tidak untuk memberikan implementasi bermanfaat yang bermakna. Metode default / metode statis adalah jenis implementasi dummy, "jika Anda mau, Anda dapat menggunakannya atau Anda dapat menimpanya (dalam hal metode default) di kelas implementasi" Dengan demikian menyelamatkan kami dari penerapan metode baru di kelas implementasi setiap kali metode baru di antarmuka sudah ditambahkan. Oleh karena itu antarmuka tidak pernah bisa sama dengan kelas abstrak.
sumber
Aturan Remi Forax adalah Anda tidak mendesain dengan kelas Abstrak. Anda mendesain aplikasi Anda dengan antarmuka . Apa pun versi Jawa, apa pun bahasanya. Hal ini didukung oleh I prinsip pemisahan nterface di SOL saya D prinsip.
Anda nanti dapat menggunakan kelas-kelas abstrak untuk memfaktisasi kode. Sekarang dengan Java 8 Anda dapat melakukannya langsung di antarmuka. Ini adalah fasilitas, tidak lebih.
sumber
Kompatibilitas mundur: Bayangkan bahwa antarmuka Anda diimplementasikan oleh ratusan kelas, memodifikasi antarmuka itu akan memaksa semua pengguna untuk menerapkan metode yang baru ditambahkan, meskipun itu mungkin tidak penting untuk banyak kelas lain yang mengimplementasikan antarmuka Anda, Plus itu memungkinkan antarmuka Anda menjadi antarmuka fungsional
Fakta & Pembatasan:
1-Mei hanya dideklarasikan dalam antarmuka dan bukan dalam kelas atau kelas abstrak.
2-Harus menyediakan tubuh
3-Ini tidak dianggap abstrak sebagai metode normal lainnya yang digunakan dalam suatu antarmuka.
sumber
Di Java 8, antarmuka terlihat seperti kelas abstrak walaupun mungkin ada beberapa perbedaan seperti:
1) Kelas abstrak adalah kelas, sehingga tidak terbatas pada batasan antarmuka lainnya di Java, misalnya kelas abstrak dapat memiliki status , tetapi Anda tidak dapat memiliki status pada antarmuka di Jawa.
2) Perbedaan semantik lain antara antarmuka dengan metode default dan kelas abstrak adalah bahwa Anda dapat mendefinisikan konstruktor di dalam kelas abstrak , tetapi Anda tidak bisa mendefinisikan konstruktor di dalam antarmuka di Jawa
sumber
Metode default di Java Interface lebih banyak digunakan untuk menyediakan implementasi dummy dari suatu fungsi sehingga menghemat kelas implementasi dari antarmuka itu dari rasa sakit menyatakan semua metode abstrak bahkan jika mereka ingin berurusan dengan hanya satu. Metode standar dalam antarmuka dengan demikian lebih merupakan pengganti konsep kelas adaptor.
Metode dalam kelas abstrak seharusnya memberikan implementasi yang bermakna dimana setiap kelas anak harus menimpa hanya jika diperlukan untuk menimpa fungsionalitas umum.
sumber
Seperti disebutkan dalam jawaban lain, kemampuan untuk menambahkan implementasi ke antarmuka ditambahkan untuk memberikan kompatibilitas mundur dalam kerangka kerja Koleksi. Saya berpendapat bahwa memberikan kompatibilitas ke belakang berpotensi satu-satunya alasan yang baik untuk menambahkan implementasi ke antarmuka.
Jika tidak, jika Anda menambahkan implementasi ke antarmuka, Anda melanggar hukum dasar mengapa antarmuka ditambahkan di tempat pertama. Java adalah bahasa pewarisan tunggal, tidak seperti C ++ yang memungkinkan untuk pewarisan berganda. Antarmuka memberikan manfaat pengetikan yang datang dengan bahasa yang mendukung multiple inheritance tanpa memperkenalkan masalah yang datang dengan multiple inheritance.
Lebih khusus lagi, Java hanya memungkinkan pewarisan tunggal dari suatu implementasi, tetapi memang memungkinkan banyak pewarisan antarmuka. Misalnya, berikut ini adalah kode Java yang valid:
MyObject
hanya mewarisi satu implementasi, tetapi mewarisi tiga kontrak.Java meneruskan beberapa warisan implementasi karena beberapa warisan implementasi disertai dengan sejumlah masalah pelik, yang berada di luar cakupan jawaban ini. Antarmuka ditambahkan untuk memungkinkan multiple inheritance of contract (alias antarmuka) tanpa masalah multiple inheritance of implementation.
Untuk mendukung pendapat saya, berikut adalah kutipan dari Ken Arnold dan James Gosling dari buku The Java Programming Language, edisi ke-4 :
sumber
Tolong pikirkan dulu prinsip buka / tutup. Metode default di antarmuka DO VIOLATE itu. Ini adalah fitur buruk di Java. Ini mendorong desain yang buruk, arsitektur yang buruk, kualitas perangkat lunak yang rendah. Saya akan menyarankan untuk menghindari menggunakan metode standar sepenuhnya.
Ajukan beberapa pertanyaan kepada diri sendiri: Mengapa Anda tidak bisa memasukkan metode Anda ke kelas abstrak? Apakah Anda memerlukan lebih dari satu kelas abstrak? Kemudian pikirkan tentang apa yang menjadi tanggung jawab kelas Anda. Apakah Anda yakin semua metode yang akan Anda masukkan ke kelas tunggal benar-benar memenuhi tujuan yang sama? Mungkin Anda akan membedakan beberapa tujuan dan kemudian akan membagi kelas Anda menjadi beberapa kelas, untuk setiap tujuan kelasnya sendiri.
sumber