Selama beberapa dekade itu menjadi hal interface yang hanya hanya (hanya) untuk menentukan metode tanda tangan. Kami diberitahu bahwa ini adalah "cara yang tepat untuk melakukan sesuatu ™".
Kemudian Java 8 keluar dan berkata:
Nah, eh, eh, sekarang Anda bisa mendefinisikan metode default. Harus lari, bye.
Saya ingin tahu bagaimana ini dicerna oleh pengembang Java berpengalaman dan mereka yang memulai baru-baru ini (beberapa tahun terakhir) mengembangkannya. Saya juga bertanya-tanya tentang bagaimana ini cocok dengan ortodoksi dan praktik Jawa.
Saya sedang membangun beberapa kode eksperimental dan ketika saya sedang melakukan beberapa refactoring, saya berakhir dengan antarmuka yang hanya memperluas antarmuka standar (Iterable) dan menambahkan dua metode standar. Dan saya akan jujur, saya merasa sangat senang tentang hal itu.
Saya tahu ini sedikit terbuka tetapi sekarang sudah ada waktu untuk Java 8 digunakan dalam proyek nyata, apakah ada ortodoksi seputar penggunaan metode standar? Apa yang saya lihat ketika dibahas adalah tentang cara menambahkan metode baru ke antarmuka tanpa merusak konsumen yang ada. Tetapi bagaimana dengan menggunakan ini dari awal seperti contoh yang saya berikan di atas. Adakah yang mengalami masalah dengan menyediakan implementasi di antarmuka mereka?
sumber
java.util.function.Function
untuk penggunaan metode default di antarmuka baru.Jawaban:
Sebuah kasus penggunaan yang bagus adalah apa yang saya sebut antarmuka "tuas": antarmuka yang hanya memiliki sejumlah kecil metode abstrak (idealnya 1), tetapi memberikan banyak "daya ungkit" karena mereka memberi Anda banyak fungsi: Anda hanya perlu menerapkan 1 metode di kelas Anda tetapi mendapatkan banyak metode lain "gratis". Pikirkan antarmuka koleksi, misalnya, dengan abstrak tunggal
foreach
metode dandefault
metode sepertimap
,fold
,reduce
,filter
,partition
,groupBy
,sort
,sortBy
, dllBerikut ini beberapa contohnya. Mari kita mulai
java.util.function.Function<T, R>
. Ini memiliki metode abstrak tunggalR apply<T>
. Dan ia memiliki dua metode default yang memungkinkan Anda menyusun fungsi dengan fungsi lain dengan dua cara berbeda, baik sebelum atau sesudah. Kedua metode komposisi tersebut diimplementasikan hanya dengan menggunakanapply
:Anda juga bisa membuat antarmuka untuk objek yang sebanding, seperti ini:
Atau kerangka kerja koleksi yang sangat disederhanakan, tempat semua operasi koleksi kembali
Collection
, terlepas dari apa jenis aslinya:Ini menjadi sangat menarik dalam kombinasi dengan lambdas, karena antarmuka "tuas" seperti itu dapat diimplementasikan oleh lambda (ini adalah antarmuka SAM).
Ini adalah kasus penggunaan yang sama dengan Metode Ekstensi ditambahkan untuk di C♯, tetapi metode default memiliki satu keuntungan berbeda: mereka adalah metode contoh yang "tepat", yang berarti mereka memiliki akses ke detail implementasi pribadi dari antarmuka (
private
metode antarmuka akan datang di Jawa 9), sedangkan Metode Ekstensi hanya gula sintaksis untuk metode statis.Jika Java pernah mendapatkan Interface Injection, itu juga akan memungkinkan tipe-safe, scoped, modular monyet-patching. Ini akan sangat menarik bagi pelaksana bahasa di JVM: saat ini, misalnya, JRuby mewarisi dari atau membungkus kelas Java untuk memberi mereka semantik Ruby tambahan, tetapi idealnya, mereka ingin menggunakan kelas yang sama. Dengan Injeksi Antarmuka dan Metode Default, mereka dapat menyuntikkan misalnya
RubyObject
antarmukajava.lang.Object
, sehingga JavaObject
dan RubyObject
adalah hal yang sama persis .sumber
Comparable
antarmuka dengan abstrakcompareTo
metode, dan standarlessThan
,lessThanOrEqual
,greaterThan
,greaterThanOrEqual
,isBetween
, danclamp
metode, semua dilaksanakan dalam halcompareTo
. Atau, lihat sajajava.util.function.Function
: ia memilikiapply
metode abstrak dan dua metode komposisi standar, keduanya diimplementasikan dalam halapply
. Saya mencoba memberikan contohCollection
antarmuka, tetapi menjadikannya semua tipe-aman itu rumit dan terlalu panjang untuk jawaban ini - saya akan mencoba untuk memberikan versi non-tipe-aman, non-tipe-melestarikan tembakan. Tetap disini.