जावा का प्रत्येक नया संस्करण पिछले वाले से अलग है। हमारे द्वारा कवर की गई सामग्री से इस तरह के बदलाव के उदाहरण के रूप में, भाषा enumsजावा 5 से पहले नहीं थी।
इंटरफेस में डिफ़ॉल्ट तरीके - 1
ठीक इसी तरह, Java 8, Java 7 से काफ़ी अलग है। बेशक, हम महत्वपूर्ण नवाचारों को नज़रअंदाज़ नहीं करेंगे। चूंकि हम इस पाठ में इंटरफेस के बारे में बात कर रहे हैं, आइए भाषा में एक अपडेट पर विचार करें: इंटरफेस में डिफ़ॉल्ट तरीके । आप पहले से ही जानते हैं कि एक इंटरफ़ेस व्यवहार को लागू नहीं करता है । इसका उद्देश्य यह वर्णन करना है कि इंटरफ़ेस को लागू करने वाली सभी वस्तुओं में क्या व्यवहार मौजूद होना चाहिए । लेकिन डेवलपर्स को अक्सर ऐसी परिस्थितियों का सामना करना पड़ता है जहां एक विधि का कार्यान्वयन सभी वर्गों में समान होता है। आइए हमारी पुरानी कार का उदाहरण देखें:

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 go() {
       System.out.println("Gas!");
   }

   @Override
   public void brake() {
       System.out.println("Brake!");
   }
}


public class F1Car implements Car {
   @Override
   public void go() {
       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 go() {
       System.out.println("This car accelerates differently!");
   }

   @Override
   public void brake() {
       System.out.println("This car slows down differently!");
   }
}
अन्य सभी 99 प्रकार की कारें डिफ़ॉल्ट पद्धति को नियोजित करेंगी, जबकिUnusualCarवर्ग अपवाद है। बड़ी तस्वीर को खराब किए बिना, यह शांतिपूर्वक अपने व्यवहार को परिभाषित करेगा। इंटरफेस में एकाधिक विरासत। जैसा कि आप पहले से ही जानते हैं, जावा में कोई एकाधिक वंशानुक्रम नहीं है। इसके लिए कई कारण हैं। हम एक अलग पाठ में उन पर विस्तार से विचार करेंगे। अन्य भाषाओं में, जैसे C++, स्थिति उलटी है। कोई भी एकाधिक वंशानुक्रम एक गंभीर चुनौती प्रस्तुत नहीं करता है, क्योंकि एक ही वस्तु में कई अलग-अलग विशेषताएं और व्यवहार हो सकते हैं। उदाहरण के लिए, हम अपने माता-पिता के लिए बच्चे हैं, अपने शिक्षकों के लिए छात्र हैं, और अपने डॉक्टरों के लिए रोगी हैं। वास्तविक जीवन में, हम विभिन्न भूमिकाएँ निभाते हैं और, तदनुसार, अलग व्यवहार करते हैं: जाहिर है कि हम शिक्षकों के साथ करीबी दोस्तों की तुलना में अलग तरह से बातचीत करते हैं। आइए इस स्थिति को कोड में अनुवाद करने का प्रयास करें। आइए कल्पना करें कि हमारे पास दो वर्ग हैं: तालाब और एवियरी। एक तालाब को तैरने वाले पक्षियों की जरूरत होती है, जबकि एक एवियरी को उड़ने वाले पक्षियों की जरूरत होती है। इसका प्रतिनिधित्व करने के लिए, हमने दो आधार वर्ग बनाए:FlyingBirdऔर Waterfowl

public class Waterfowl {
}

public class FlyingBird {
}
तदनुसार, हम उन पक्षियों को भेजेंगे जो विरासत में FlyingBirdएवियरी में आएंगे, जबकि जो प्राप्त होंगे वे Waterfowlतालाब में जाएंगे। सब कुछ सीधा सा लगता है। लेकिन अगर हमें कहीं बतख परिभाषित करने की ज़रूरत है तो हमें क्या करना चाहिए? बतख दोनों तैरती और उड़ती हैं। लेकिन हमारे पास एकाधिक विरासत नहीं है। सौभाग्य से, जावा इंटरफेस के कई कार्यान्वयन का समर्थन करता है। यदि एक वर्ग कई माता-पिता को विरासत में नहीं दे सकता है, तो कई इंटरफेस को लागू करना आसान है! हमारा बत्तख एक उड़ने वाला पक्षी होने के साथ-साथ एक तैरने वाला पक्षी भी हो सकता है :) वांछित परिणाम प्राप्त करने के लिए, हमें कक्षाओं के बजाय केवल बनाने FlyingBirdऔर इंटरफेस करने की आवश्यकता है।Waterfowl

public class Duck implements FlyingBird, Waterfowl {

   // Methods of both interfaces combine easily into one class
  
   @Override
   public void fly() {
       System.out.println("Flying!");
   }

   @Override
   public void swim() {

       System.out.println("Swimming!");
   }
}
इसका अर्थ है कि हमारा कार्यक्रम लचीले ढंग से कक्षाओं को प्रबंधित करने की क्षमता को बरकरार रखता है। जब हम इसे डिफ़ॉल्ट तरीकों से जोड़ते हैं, तो वस्तुओं के व्यवहार को निर्धारित करने की हमारी क्षमता लगभग असीमित हो जाती है! :)