जावा का हर नया संस्करण पिछले वाले से अलग है। यहाँ सामग्री में परिवर्तनों का एक उदाहरण दिया गया है जिसे हमने कवर किया है: Java 5 से पहले, भाषा में
इसी तरह, जावा 8 जावा 7 से स्पष्ट रूप से भिन्न है। हमारे अधिकांश पाठ भाषा के 7वें संस्करण के लिए लिखे गए थे, लेकिन निश्चित रूप से हम महत्वपूर्ण नवाचारों की उपेक्षा नहीं करेंगे। चूंकि हम पहले से ही इस पाठ में इंटरफेस के बारे में बात कर रहे हैं, हम एक अपडेट पर विचार करेंगे - इंटरफेस में डिफ़ॉल्ट तरीके । आप पहले से ही जानते हैं कि एक इंटरफ़ेस व्यवहार को लागू नहीं करता है । इसका कार्य उस व्यवहार का वर्णन करना है जो इसे लागू करने वाली सभी वस्तुओं में होना चाहिए. लेकिन डेवलपर्स को अक्सर ऐसी स्थितियों का सामना करना पड़ता है जहां एक विधि का कार्यान्वयन सभी वर्गों में समान होता है। आइए हमारी पुरानी कार के उदाहरण पर विचार करें:
enum
s नहीं था। ![इंटरफेस में डिफ़ॉल्ट तरीके - 1](https://cdn.codegym.cc/images/article/34d25d0e-f8da-43f7-ab2b-5333c5a01585/800.jpeg)
public interface Car {
public void gas();
public void brake();
}
public class Sedan implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
public class Truck implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
public class F1Car implements Car {
@Override
public void gas() {
System.out.println("Gas!");
}
@Override
public void brake() {
System.out.println("Brake!");
}
}
"आपकी राय में, इस कोड के साथ मुख्य समस्या क्या है? आपने शायद देखा है कि हमने बार-बार कोड का एक गुच्छा लिखा है! प्रोग्रामिंग में यह समस्या आम है, और आपको इससे बचने की आवश्यकता है। यह अलग बात है कि विशेष समाधान पहले मौजूद नहीं थे जावा 8 जारी किया गया था। इस संस्करण के साथ डिफ़ॉल्ट विधियों को निर्दिष्ट करने और इंटरफ़ेस के अंदर उन्हें लागू करने की क्षमता आई ! यहां बताया गया है कि आप यह कैसे करते हैं:
public interface Car {
public default void gas() {
System.out.println("Gas!");
}
public default void brake() {
System.out.println("Brake!");
}
}
public class Sedan implements Car {
}
public class Truck implements Car {
}
public class F1Car implements Car {
}
अब gas()
और brake()
तरीके, जो सभी कारों के लिए समान थे, इंटरफ़ेस में स्थानांतरित कर दिए गए हैं। बार-बार कोड की जरूरत नहीं है। क्या अधिक है, प्रत्येक वर्ग में विधियाँ उपलब्ध हैं!
public class Main {
public static void main(String[] args) {
F1Car f1Car = new F1Car();
Sedan sedan = new Sedan();
Truck truck = new Truck();
truck.gas();
sedan.gas();
f1Car.brake();
}
}
क्या होगा यदि विधि के साथ 100 वर्ग हैं gas()
, लेकिन उनमें से केवल 99 का व्यवहार समान है? क्या यह सबकुछ बर्बाद कर देता है और इस स्थिति के लिए डिफ़ॉल्ट विधि को अनुपयुक्त बना देता है? बिल्कुल नहीं :) इंटरफेस में डिफ़ॉल्ट तरीकों को उसी तरह से ओवरराइड किया जा सकता है जैसे सामान्य लोगों को।
public class UnusualCar implements Car {
@Override
public void gas() {
System.out.println("This car accelerates differently!");
}
@Override
public void brake() {
System.out.println("This car decelerates differently!");
}
}
अन्य सभी 99 प्रकार की कारें डिफ़ॉल्ट पद्धति को लागू करेंगी, औरUnusualCar
वर्ग, जो एक अपवाद है, समग्र चित्र को खराब नहीं करेगा और शांतिपूर्वक अपने व्यवहार को परिभाषित करेगा। इंटरफेस की एकाधिक विरासत। जैसा कि आप पहले से ही जानते हैं, जावा एकाधिक वंशानुक्रम का समर्थन नहीं करता है। इसके लिए कई कारण हैं। हम उन्हें एक अलग पाठ में विस्तार से देखेंगे। अन्य भाषाएँ, जैसे C++, इसका समर्थन करती हैं। एकाधिक वंशानुक्रम के बिना, एक गंभीर समस्या उत्पन्न होती है: एक वस्तु में कई अलग-अलग विशेषताएँ और 'व्यवहार' हो सकते हैं। यहाँ जीवन से एक उदाहरण है: हम अपने माता-पिता के लिए बच्चे हैं, अपने शिक्षकों के लिए छात्र हैं, और अपने डॉक्टरों के लिए रोगी हैं। जीवन में, हम अलग-अलग भूमिकाएँ निभाते हैं और तदनुसार, अलग-अलग व्यवहार करते हैं: जाहिर है, हम शिक्षकों से उसी तरह बात नहीं करेंगे जैसे हम अपने करीबी दोस्तों से करते हैं। आइए इसे कोड में अनुवाद करने का प्रयास करें। कल्पना कीजिए कि हमारे पास दो वर्ग हैं: तालाब और एवियरी। तालाब के लिए हमें जलपक्षी चाहिए; एवियरी के लिए हमें उड़ने वाले पक्षियों की जरूरत है। ऐसा करने के लिए, हमने दो आधार वर्ग बनाए हैं:FlyingBird
और Waterfowl
।
public class Waterfowl {
}
public class FlyingBird {
}
तदनुसार, हम उन पक्षियों को भेजेंगे जिनकी कक्षाएं FlyingBird
एवियरी को विरासत में मिली हैं, और हम उन पक्षियों को भेजेंगे जो Waterfowl
तालाब को विरासत में देंगे। यह सब बहुत सरल लगता है. लेकिन हम बतख कहाँ भेजते हैं? यह तैरता है और उड़ता है। और हमारे पास एकाधिक वंशानुक्रम नहीं है। सौभाग्य से, जावा इंटरफेस के कई कार्यान्वयन का समर्थन करता है। हालाँकि एक वर्ग कई माता-पिता को विरासत में नहीं दे सकता है, यह आसानी से कई इंटरफेस को लागू कर सकता है! हमारा बतख एक उड़ने वाला पक्षी और एक जलपक्षी दोनों हो सकता है :) हमें वांछित परिणाम प्राप्त करने के लिए कक्षाओं के बजाय बस बनाने FlyingBird
और इंटरफेस करने की आवश्यकता है।Waterfowl
public class Duck implements FlyingBird, Waterfowl {
// The methods of both interfaces can be easily combined into one class
@Override
public void fly() {
System.out.println("Fly!");
}
@Override
public void swim() {
System.out.println("Swim!");
}
}
तदनुसार, हमारा कार्यक्रम कक्षाओं के लचीलेपन को बरकरार रखता है, और डिफ़ॉल्ट तरीकों के संयोजन में, वस्तुओं के व्यवहार को परिभाषित करने की हमारी क्षमता लगभग असीमित हो जाती है! :)