एक महान उपयोग-मामला यह है कि मैं "लीवर" इंटरफेस को क्या कहता हूं: इंटरफेस जो केवल अमूर्त विधियों की एक छोटी संख्या है (आदर्श रूप से 1), लेकिन इसमें "लीवरेज" बहुत प्रदान करते हैं जो आपको बहुत अधिक कार्यक्षमता प्रदान करते हैं: आप केवल अपनी कक्षा में 1 विधि को लागू करने की आवश्यकता है, लेकिन "मुफ़्त" के लिए कई अन्य तरीके प्राप्त करें। एक भी सार के साथ, एक मेमोरी इंटरफ़ेस के बारे में सोचो, उदाहरण के लिए foreach
विधि और default
तरीकों की तरह map
, fold
, reduce
, filter
, partition
, groupBy
, sort
, sortBy
, आदि
यहां कुछ उदाहरण दिए गए हैं। के साथ शुरू करते हैं java.util.function.Function<T, R>
। इसकी एक एकल सार विधि है R apply<T>
। और इसकी दो डिफ़ॉल्ट विधियां हैं जो आपको दो अलग-अलग तरीकों से फ़ंक्शन की रचना करने देती हैं, या तो पहले या बाद में। उन दोनों रचना विधियों को सिर्फ उपयोग करके लागू किया जाता हैapply
:
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));
}
आप तुलनीय वस्तुओं के लिए एक इंटरफ़ेस भी बना सकते हैं, कुछ इस तरह से:
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());
}
}
या एक अत्यंत सरलीकृत संग्रह रूपरेखा, जहां सभी संग्रह संचालन वापस आते हैं Collection
, भले ही मूल प्रकार क्या हो:
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)
}
}
यह लैम्ब्डा के साथ संयोजन में बहुत दिलचस्प हो जाता है, क्योंकि इस तरह के "लीवर" इंटरफ़ेस को लैम्ब्डा (यह एसएएम इंटरफ़ेस है) द्वारा लागू किया जा सकता है।
यह वही उपयोग-केस है जिसे C but में एक्सटेंशन मेथड्स के लिए जोड़ा गया था, लेकिन डिफ़ॉल्ट तरीकों का एक अलग फायदा है: वे "उचित" उदाहरण के तरीके हैं, जिसका अर्थ है कि उनके पास इंटरफ़ेस के निजी कार्यान्वयन विवरण तक पहुंच है ( private
इंटरफ़ेस मेथड आ रहे हैं जावा 9 में), जबकि एक्सटेंशन मेथड्स स्टैटिक मेथड के लिए सिंटैक्टिक शुगर हैं।
जावा को कभी इंटरफ़ेस इंजेक्शन मिलना चाहिए, यह टाइप-सेफ, स्कोप्ड, मॉड्यूलर बंदर-पैचिंग की भी अनुमति देगा। यह JVM पर भाषा कार्यान्वयनकर्ताओं के लिए बहुत दिलचस्प होगा: फिलहाल, उदाहरण के लिए, JRuby या तो अतिरिक्त रूबी शब्दार्थ के साथ प्रदान करने के लिए जावा कक्षाओं से विरासत में लेता है या उन्हें लपेटता है, लेकिन आदर्श रूप से, वे उसी कक्षाओं का उपयोग करना चाहते हैं। इंटरफ़ेस इंजेक्शन के तरीके के साथ और चूक, वे इंजेक्षन सकता है जैसे एक RubyObject
इंटरफेस में java.lang.Object
है, ताकि एक जावा Object
और एक रूबी Object
हैं सटीक एक ही बात ।