জাভার প্রতিটি নতুন সংস্করণ পূর্ববর্তী সংস্করণ থেকে পৃথক। আমরা কভার করেছি উপাদান থেকে এই ধরনের পরিবর্তনের উদাহরণ হিসাবে, ভাষাটি enumsJava 5 এর আগে ছিল না।
ইন্টারফেসে ডিফল্ট পদ্ধতি - 1
ঠিক তাই, জাভা 8 জাভা 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();
   }
}
যদি একটি gas()পদ্ধতি সহ 100টি ক্লাস থাকে তবে তাদের মধ্যে মাত্র 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!");
   }
}
এর মানে হল যে আমাদের প্রোগ্রামটি নমনীয়ভাবে ক্লাস পরিচালনা করার ক্ষমতা ধরে রাখে। যখন আমরা এটিকে ডিফল্ট পদ্ধতির সাথে একত্রিত করি, তখন বস্তুর আচরণ নির্ধারণ করার আমাদের ক্ষমতা প্রায় সীমাহীন হয়ে যায়! :)