Java 8 इंटरफेस में डिफ़ॉल्ट मेथड कार्यान्वयन की एक नई अवधारणा पेश करता है। यह क्षमता बैकवर्ड कम्पैटिबिलिटी के लिए जोड़ी गई है ताकि पुराने इंटरफेस Java 8 की लैम्ब्डा एक्सप्रेशन क्षमता का लाभ उठा सकें।
उदाहरण के लिए, List या Collection इंटरफेस में forEach मेथड डिक्लेरेशन नहीं है। इस तरह के मेथड को जोड़ने से केवल कलेक्शन फ्रेमवर्क इम्प्लीमेंटेशन्स टूट जाएंगे। Java 8 डिफ़ॉल्ट मेथड पेश करता है ताकि List/Collection इंटरफेस में forEach मेथड का डिफ़ॉल्ट कार्यान्वयन हो सके, और इन इंटरफेसेस को इम्प्लीमेंट करने वाली क्लास को इसे इम्प्लीमेंट करने की आवश्यकता नहीं है।
उदाहरण
public class Java8Tester {
public static void main(String args[]) {
Vehicle vehicle = new Car();
vehicle.print();
}
}
interface Vehicle {
default void print() {
System.out.println("I am a vehicle!");
}
static void blowHorn() {
System.out.println("Blowing horn!!!");
}
}
interface FourWheeler {
default void print() {
System.out.println("I am a four wheeler!");
}
}
class Car implements Vehicle, FourWheeler {
@Override
public void print() {
Vehicle.super.print();
FourWheeler.super.print();
Vehicle.blowHorn();
System.out.println("I am a car!");
}
}
आउटपुट
I am a vehicle! I am a four wheeler! Blowing horn!!! I am a car!
डिफ़ॉल्ट मेथड्स - मुख्य विशेषताएं
- कीवर्ड:
defaultमेथड सिग्नेचर से पहले - बॉडी होती है: एब्स्ट्रैक्ट मेथड्स के विपरीत, इनका कार्यान्वयन होता है
- विरासत में मिलते हैं: इम्प्लीमेंटिंग क्लास को स्वचालित रूप से मिलते हैं
- ओवरराइड किए जा सकते हैं: इम्प्लीमेंटिंग क्लास इन्हें ओवरराइड कर सकती है
- मल्टीपल इंटरफेस संघर्ष: यदि दो इंटरफेस में समान सिग्नेचर का डिफ़ॉल्ट मेथड हो, तो क्लास को अनिवार्य रूप से ओवरराइड करना होगा
डायमंड प्रॉब्लम समाधान
interface A {
default void show() { System.out.println("A"); }
}
interface B {
default void show() { System.out.println("B"); }
}
// कंपाइल एरर: Duplicate default methods
// class C implements A, B {}
// सही: ओवरराइड करना आवश्यक
class C implements A, B {
@Override
public void show() {
A.super.show(); // विशिष्ट इंटरफेस का डिफ़ॉल्ट कॉल
// या B.super.show();
System.out.println("C");
}
}
सुपर कॉल सिंटैक्स
interface Parent {
default void foo() { System.out.println("Parent"); }
}
interface Child extends Parent {
default void foo() {
Parent.super.foo(); // पेरेंट का डिफ़ॉल्ट कॉल
System.out.println("Child");
}
}
उपयोग के मामले
- API विकास (API Evolution): मौजूदा इंटरफेस में नए मेथड्स जोड़ना बिना सभी इम्प्लीमेंटर्स को तोड़े
- वैकल्पिक व्यवहार: सामान्य डिफ़ॉल्ट प्रदान करना जिसे ओवरराइड किया जा सकता है
- लैम्ब्डा सक्षम करना: फंक्शनल इंटरफेस में हेल्पर मेथड्स (जैसे
Predicate.and(),Stream.filter())
Java API में उदाहरण
| इंटरफेस | डिफ़ॉल्ट मेथड | विवरण |
|---|---|---|
| Collection | stream(), parallelStream(), forEach() | स्ट्रीम API सक्षम करना |
| List | sort(Comparator), replaceAll() | सुविधा मेथड्स |
| Map | getOrDefault(), putIfAbsent(), compute() | एटॉमिक ऑपरेशन्स |
| Comparator | reversed(), thenComparing(), nullsFirst() | कंपोज़िशन |
| Predicate | and(), or(), negate() | लॉजिकल संयोजन |
| Iterable | forEach(), spliterator() | स्ट्रीम इंटीग्रेशन |
डिफ़ॉल्ट मेथड्स के नियम
Objectक्लास के मेथड्स (toString,equals,hashCode) के लिए डिफ़ॉल्ट मेथड नहीं हो सकता- डिफ़ॉल्ट मेथड्स
finalयाsynchronizedनहीं हो सकते - एक इंटरफेस दूसरे को एक्सटेंड करता है तो चाइल्ड पेरेंट के डिफ़ॉल्ट को ओवरराइड कर सकता है
निष्कर्ष: डिफ़ॉल्ट मेथड्स Java 8 की एक क्रांतिकारी विशेषता है जो इंटरफेस को विकसित (evolve) करने की अनुमति देती है बिना मौजूदा इम्प्लीमेंटेशन्स को तोड़े। ये लैम्ब्डा एक्सप्रेशंस और स्ट्रीम API की नींव हैं।