Jawaban singkatnya adalah: aman jika Anda menggunakannya dengan aman :)
Jawaban yang tajam: beri tahu saya apa yang Anda maksud dengan sifat, dan mungkin saya akan memberikan jawaban yang lebih baik :)
Secara serius, istilah "sifat" tidak didefinisikan dengan baik. Banyak pengembang Java yang paling akrab dengan ciri-ciri seperti yang diungkapkan dalam Scala, tetapi Scala jauh dari bahasa pertama yang memiliki ciri-ciri, baik dalam nama atau efeknya.
Misalnya, di Scala, sifat bersifat stateful (dapat memiliki var
variabel); di Fortress mereka adalah perilaku murni. Antarmuka Java dengan metode default tidak memiliki kewarganegaraan; apakah ini berarti mereka bukan sifat? (Petunjuk: itu adalah pertanyaan jebakan.)
Sekali lagi, di Scala, ciri-ciri disusun melalui linierisasi; jika kelas A
memperluas ciri X
- ciri dan Y
, maka urutan di mana X
dan Y
dicampur menentukan bagaimana konflik antara X
dan Y
diselesaikan. Di Java, mekanisme linierisasi ini tidak ada (sebagian ditolak karena terlalu "tidak mirip Java".)
Alasan terdekat untuk menambahkan metode default ke antarmuka adalah untuk mendukung evolusi antarmuka , tetapi kami sangat menyadari bahwa kami melampaui itu. Apakah Anda menganggap itu sebagai "evolusi antarmuka ++" atau "sifat--" adalah masalah interpretasi pribadi. Jadi, untuk menjawab pertanyaan Anda tentang keselamatan ... selama Anda tetap berpegang pada apa yang sebenarnya didukung oleh mekanisme tersebut, daripada mencoba meregangkannya ke sesuatu yang tidak didukungnya, Anda akan baik-baik saja.
Tujuan desain utama adalah bahwa, dari perspektif klien antarmuka, metode default harus dibedakan dari metode antarmuka "biasa". Default-an suatu metode, oleh karena itu, hanya menarik bagi perancang dan pelaksana antarmuka.
Berikut beberapa kasus penggunaan yang sesuai dengan tujuan desain:
Evolusi antarmuka. Di sini, kami menambahkan metode baru ke antarmuka yang ada, yang memiliki implementasi default yang masuk akal dalam kaitannya dengan metode yang ada pada antarmuka itu. Contohnya adalah menambahkan forEach
metode ke Collection
, di mana implementasi default ditulis dalam istilah iterator()
metode.
Metode "opsional". Di sini, perancang antarmuka mengatakan "Pelaksana tidak perlu mengimplementasikan metode ini jika mereka bersedia untuk hidup dengan keterbatasan dalam fungsionalitas yang diperlukan". Misalnya, Iterator.remove
diberi default yang melempar UnsupportedOperationException
; karena sebagian besar implementasi Iterator
memiliki perilaku ini, default membuat metode ini pada dasarnya opsional. (Jika perilaku dari AbstractCollection
diekspresikan sebagai default pada Collection
, kita mungkin melakukan hal yang sama untuk metode mutatif.)
Metode kenyamanan. Ini adalah metode yang hanya untuk kenyamanan, sekali lagi umumnya diimplementasikan dalam istilah metode non-default di kelas. The logger()
metode dalam contoh pertama Anda adalah ilustrasi yang wajar ini.
Kombinator. Ini adalah metode komposisi yang membuat instance baru dari antarmuka berdasarkan instance saat ini. Misalnya metode Predicate.and()
atau Comparator.thenComparing()
contoh kombinator.
Jika Anda memberikan implementasi default, Anda juga harus memberikan beberapa spesifikasi untuk default (di JDK, kami menggunakan @implSpec
tag javadoc untuk ini) untuk membantu pelaksana dalam memahami apakah mereka ingin mengganti metode atau tidak. Beberapa default, seperti metode kemudahan dan kombinator, hampir tidak pernah diganti; yang lain, seperti metode opsional, sering diganti. Anda perlu memberikan spesifikasi yang cukup (bukan hanya dokumentasi) tentang apa yang dijanjikan default untuk dilakukan, sehingga implementor dapat membuat keputusan yang masuk akal tentang apakah mereka perlu menimpanya.