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 dan default
metode seperti map
, fold
, reduce
, filter
, partition
, groupBy
, sort
, sortBy
, dll
Berikut ini beberapa contohnya. Mari kita mulai java.util.function.Function<T, R>
. Ini memiliki metode abstrak tunggal R 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
:
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
return (T t) -> after.apply(apply(t));
}
Anda juga bisa membuat antarmuka untuk objek yang sebanding, seperti ini:
interface MyComparable<T extends MyComparable<T>> {
int compareTo(T other);
default boolean lessThanOrEqual(T other) {
return compareTo(other) <= 0;
}
default boolean lessThan(T other) {
return compareTo(other) < 0;
}
default boolean greaterThanOrEqual(T other) {
return compareTo(other) >= 0;
}
default boolean greaterThan(T other) {
return compareTo(other) > 0;
}
default boolean isBetween(T min, T max) {
return greaterThanOrEqual(min) && lessThanOrEqual(max);
}
default T clamp(T min, T max) {
if (lessThan( min)) return min;
if (greaterThan(max)) return max;
return (T)this;
}
}
class CaseInsensitiveString implements MyComparable<CaseInsensitiveString> {
CaseInsensitiveString(String s) { this.s = s; }
private String s;
@Override public int compareTo(CaseInsensitiveString other) {
return s.toLowerCase().compareTo(other.s.toLowerCase());
}
}
Atau kerangka kerja koleksi yang sangat disederhanakan, tempat semua operasi koleksi kembali Collection
, terlepas dari apa jenis aslinya:
interface MyCollection<T> {
void forEach(java.util.function.Consumer<? super T> f);
default <R> java.util.Collection<R> map(java.util.function.Function<? super T, ? extends R> f) {
java.util.Collection<R> l = new java.util.ArrayList();
forEach(el -> l.add(f.apply(el)));
return l;
}
}
class MyArray<T> implements MyCollection<T> {
private T[] array;
MyArray(T[] array) { this.array = array; }
@Override public void forEach(java.util.function.Consumer<? super T> f) {
for (T el : array) f.accept(el);
}
@Override public String toString() {
StringBuilder sb = new StringBuilder("(");
map(el -> el.toString()).forEach(s -> { sb.append(s); sb.append(", "); } );
sb.replace(sb.length() - 2, sb.length(), ")");
return sb.toString();
}
public static void main(String... args) {
MyArray<Integer> array = new MyArray<>(new Integer[] {1, 2, 3, 4});
System.out.println(array);
// (1, 2, 3, 4)
}
}
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
antarmuka java.lang.Object
, sehingga Java Object
dan Ruby Object
adalah hal yang sama persis .