CodeGym /Java Blog /এলোমেলো /কেন আমাদের জাভাতে ইন্টারফেস দরকার?
John Squirrels
লেভেল 41
San Francisco

কেন আমাদের জাভাতে ইন্টারফেস দরকার?

এলোমেলো দলে প্রকাশিত
ওহে! আজ আমরা জাভাতে একটি গুরুত্বপূর্ণ ধারণা সম্পর্কে কথা বলতে যাচ্ছি: ইন্টারফেস। শব্দটি সম্ভবত আপনার পরিচিত। উদাহরণস্বরূপ, বেশিরভাগ কম্পিউটার প্রোগ্রাম এবং গেমের ইন্টারফেস রয়েছে। একটি বিস্তৃত অর্থে, একটি ইন্টারফেস হল এক ধরনের 'রিমোট কন্ট্রোল' যা দুটি মিথস্ক্রিয়াকারী পক্ষকে সংযুক্ত করে। দৈনন্দিন জীবনে একটি ইন্টারফেসের একটি সাধারণ উদাহরণ হল একটি টিভি রিমোট কন্ট্রোল। এটি দুটি বস্তুকে সংযুক্ত করে — একজন ব্যক্তি এবং একটি টিভি — এবং বিভিন্ন কাজ সম্পাদন করে: ভলিউম বাড়ানো বা কমানো, চ্যানেল স্যুইচ করা এবং টিভি চালু বা বন্ধ করা। একটি পক্ষকে (ব্যক্তির) ইন্টারফেসটি অ্যাক্সেস করতে হবে (রিমোট কন্ট্রোলে একটি বোতাম টিপুন) যাতে দ্বিতীয় পক্ষকে কাজটি সম্পাদন করতে হয়। উদাহরণস্বরূপ, পরবর্তী চ্যানেলে টিভি পরিবর্তন করতে। আরো কি, ব্যবহারকারী না টিভি কীভাবে সংগঠিত হয় বা কীভাবে চ্যানেল পরিবর্তন প্রক্রিয়া অভ্যন্তরীণভাবে প্রয়োগ করা হয় তা জানতে হবে। ব্যবহারকারীর অ্যাক্সেস আছে একমাত্র জিনিস ইন্টারফেস. মূল উদ্দেশ্য কাঙ্ক্ষিত ফলাফল পাওয়া। প্রোগ্রামিং এবং জাভার সাথে এর কি সম্পর্ক? সবকিছু :) একটি ইন্টারফেস তৈরি করা একটি নিয়মিত ক্লাস তৈরির অনুরূপ, কিন্তু পরিবর্তে শব্দ ব্যবহার করেক্লাস , আমরা শব্দ ইন্টারফেস নির্দেশ করে . আসুন সহজতম জাভা ইন্টারফেসটি দেখি, এটি কীভাবে কাজ করে এবং কেন আমাদের এটির প্রয়োজন হবে তা দেখুন:

public interface CanSwim {

     public void swim();
}
আমরা একটি CanSwim ইন্টারফেস তৈরি করেছি। এটি কিছুটা আমাদের রিমোট কন্ট্রোলের মতো, কিন্তু একটি 'বোতাম' সহ: swim() পদ্ধতি। কিন্তু কিভাবে আমরা এই রিমোট কন্ট্রোলার ব্যবহার করব? এটি করার জন্য, আমাদের একটি পদ্ধতি প্রয়োগ করতে হবে, অর্থাৎ আমাদের রিমোট কন্ট্রোল বোতাম। একটি ইন্টারফেস ব্যবহার করতে, আমাদের প্রোগ্রামের কিছু ক্লাস অবশ্যই এর পদ্ধতিগুলি বাস্তবায়ন করবে। আসুন এমন একটি শ্রেণী উদ্ভাবন করি যার বস্তু 'সাঁতার কাটতে পারে'। উদাহরণস্বরূপ, একটি হাঁসের ক্লাস ফিট করে:

public class Duck implements CanSwim {

    public void swim() {
        System.out.println("Duck, swim!");
    }

    public static void main(String[] args) {

        Duck duck = new Duck();
        duck.swim();
    }
}
"আমরা এখানে কি দেখতে পাচ্ছি? হাঁস ক্লাসটি ইমপ্লিমেন্টস কীওয়ার্ড দ্বারা ক্যানসুইম ইন্টারফেসের সাথে 'সম্পর্কিত' । আপনি মনে করতে পারেন যে আমরা উত্তরাধিকারের মাধ্যমে দুটি শ্রেণীকে সংযুক্ত করার জন্য একটি অনুরূপ প্রক্রিয়া ব্যবহার করেছি, কিন্তু সেক্ষেত্রে আমরা প্রসারিত শব্দটি ব্যবহার করেছি। সম্পূর্ণ স্পষ্টতা, আমরা ' পাবলিক ক্লাস ডক ইমপ্লিমেন্টস ক্যানসুইম ' আক্ষরিকভাবে অনুবাদ করতে পারি : 'পাবলিক ডাক ক্লাস ক্যানসুইম ইন্টারফেস প্রয়োগ করে'। এর মানে হল যে একটি ইন্টারফেসের সাথে যুক্ত একটি ক্লাসকে অবশ্যই তার সমস্ত পদ্ধতি প্রয়োগ করতে হবে। নোট: আমাদের ক্লাস, ঠিক যেমন ইন্টারফেসের একটি পদ্ধতি রয়েছে এবং এতে কিছু যুক্তি রয়েছে। এটি একটি বাধ্যতামূলক প্রয়োজন। আমরা যদি শুধু লিখিDuckCanSwimswim()public class Duck implements CanSwimswim()ক্লাসে একটি পদ্ধতি তৈরি না করে Duck, কম্পাইলার আমাদের একটি ত্রুটি দেবে: হাঁস বিমূর্ত নয় এবং CanSwim-এ বিমূর্ত পদ্ধতি swim() ওভাররাইড করে না কেন? কেন এটা ঘটবে? যদি আমরা টিভি উদাহরণ ব্যবহার করে ত্রুটিটি ব্যাখ্যা করি, তাহলে এটা হবে কাউকে একটি 'চ্যানেল পরিবর্তন করুন' বোতাম দিয়ে একটি টিভি রিমোট কন্ট্রোল দেওয়ার মতো যা চ্যানেল পরিবর্তন করতে পারে না। আপনি যত খুশি বোতাম টিপতে পারেন, কিন্তু এটি কাজ করবে না। রিমোট কন্ট্রোল নিজেই চ্যানেল পরিবর্তন করে না: এটি শুধুমাত্র টিভিতে একটি সংকেত পাঠায়, যা চ্যানেল পরিবর্তনের জটিল প্রক্রিয়াটি বাস্তবায়ন করে। এবং তাই এটি আমাদের হাঁসের সাথে: এটি অবশ্যই সাঁতার জানতে হবে যাতে এটি ইন্টারফেস ব্যবহার করে বলা যেতে পারে CanSwim। এটা কিভাবে জানি না, তাহলেCanSwimইন্টারফেস দুটি পক্ষকে সংযুক্ত করে না - ব্যক্তি এবং প্রোগ্রাম। ব্যক্তি প্রোগ্রামের ভিতরে সাঁতার swim()কাটতে পদ্ধতিটি ব্যবহার করতে পারবে না। Duckএখন আপনি আরও স্পষ্টভাবে বুঝতে পারছেন যে ইন্টারফেসগুলি কীসের জন্য। একটি ইন্টারফেস এমন আচরণ বর্ণনা করে যা ইন্টারফেস বাস্তবায়নকারী ক্লাসের অবশ্যই থাকতে হবে। 'আচরণ' পদ্ধতির একটি সংগ্রহ। আমরা যদি বেশ কয়েকটি মেসেঞ্জার তৈরি করতে চাই তবে সবচেয়ে সহজ কাজটি হল একটি Messengerইন্টারফেস তৈরি করা। প্রত্যেক বার্তাবাহকের কি প্রয়োজন? একটি মৌলিক স্তরে, তারা অবশ্যই বার্তা গ্রহণ এবং পাঠাতে সক্ষম হবে।

public interface Messenger{

     public void sendMessage();

     public void getMessage();
}
এখন আমরা কেবল আমাদের মেসেঞ্জার ক্লাস তৈরি করতে পারি যা সংশ্লিষ্ট ইন্টারফেস বাস্তবায়ন করে। কম্পাইলার নিজেই আমাদের ক্লাসে এগুলি বাস্তবায়ন করতে আমাদের 'জোর' করবে। টেলিগ্রাম:

public class Telegram implements Messenger {

    public void sendMessage() {

        System.out.println("Sending a Telegram message!");
    }

     public void getMessage() {
         System.out.println("Receiving a Telegram message!");
     }
}
হোয়াটসঅ্যাপ:

public class WhatsApp implements Messenger {

    public void sendMessage() {

        System.out.println("Sending a WhatsApp message!");
    }

     public void getMessage() {
         System.out.println("Reading a WhatsApp message!");
     }
}
ভাইবার:

public class Viber implements Messenger {

    public void sendMessage() {

        System.out.println("Sending a Viber message!");
    }

     public void getMessage() {
         System.out.println("Receiving a Viber message!");
     }
}
এই সুবিধা কি প্রদান করে? তাদের মধ্যে সবচেয়ে গুরুত্বপূর্ণ হল আলগা কাপলিং। কল্পনা করুন যে আমরা একটি প্রোগ্রাম ডিজাইন করছি যা ক্লায়েন্ট ডেটা সংগ্রহ করবে। Clientক্লায়েন্ট কোন নির্দিষ্ট মেসেঞ্জার ব্যবহার করছে তা নির্দেশ করার জন্য ক্লাসের অবশ্যই একটি ক্ষেত্র প্রয়োজন । ইন্টারফেস ছাড়া, এটি অদ্ভুত দেখাবে:

public class Client {

    private WhatsApp whatsApp;
    private Telegram telegram;
    private Viber viber;
}
আমরা তিনটি ক্ষেত্র তৈরি করেছি, কিন্তু একজন ক্লায়েন্টের শুধুমাত্র একটি মেসেঞ্জার থাকতে পারে। আমরা শুধু জানি না কোনটি। তাই ক্লায়েন্টের সাথে যোগাযোগ করতে সক্ষম হওয়ার জন্য আমাদের ক্লাসে প্রতিটি সম্ভাবনা যুক্ত করতে হবে। দেখা যাচ্ছে যে তাদের মধ্যে এক বা দুটি সর্বদা হবে null, প্রোগ্রামের দ্বারা সম্পূর্ণরূপে অপ্রয়োজনীয়। পরিবর্তে আমাদের ইন্টারফেস ব্যবহার করা ভাল:

public class Client {

    private Messenger messenger;
}
এটি লুজ কাপলিং এর উদাহরণ! ক্লাসে একটি নির্দিষ্ট মেসেঞ্জার ক্লাস নির্দিষ্ট করার পরিবর্তে Client, আমরা শুধু ইঙ্গিত করি যে ক্লায়েন্টের একটি মেসেঞ্জার আছে। প্রোগ্রাম চালানোর সময় ঠিক কোনটি নির্ধারণ করা হবে। কিন্তু কেন আমরা এই জন্য ইন্টারফেস প্রয়োজন? কেন তারা এমনকি ভাষা যোগ করা হয়েছে? এটি একটি ভাল প্রশ্ন - এবং সঠিক প্রশ্ন! আমরা কি সাধারণ উত্তরাধিকার ব্যবহার করে একই ফলাফল অর্জন করতে পারি না? Messengerঅভিভাবক হিসাবে শ্রেণী, এবং , Viber, Telegramএবং WhatsAppশিশু হিসাবে। আসলে, এটা সম্ভব। কিন্তু একটা বাধা আছে। আপনি ইতিমধ্যে জানেন, জাভা কোন একাধিক উত্তরাধিকার আছে. কিন্তু একাধিক ইন্টারফেসের জন্য সমর্থন আছে। একটি ক্লাস আপনি যতগুলি চান ততগুলি ইন্টারফেস বাস্তবায়ন করতে পারে। কল্পনা করুন যে আমাদের একটি Smartphoneক্লাস আছে যার একটি আছেAppক্ষেত্র, যা স্মার্টফোনে ইনস্টল করা একটি অ্যাপ উপস্থাপন করে।

public class Smartphone {

    private App app;
}
অবশ্যই, একটি অ্যাপ এবং একটি মেসেঞ্জার একই, কিন্তু তারা এখনও ভিন্ন জিনিস। একটি মেসেঞ্জারের মোবাইল এবং ডেস্কটপ সংস্করণ থাকতে পারে, তবে অ্যাপ বিশেষভাবে একটি মোবাইল অ্যাপের প্রতিনিধিত্ব করে। এখানে চুক্তি - যদি আমরা উত্তরাধিকার ব্যবহার করি, আমরা ক্লাসে একটি Telegramবস্তু যোগ করতে সক্ষম হব না Smartphone। সর্বোপরি, Telegramক্লাস একই সাথে উত্তরাধিকারী হতে পারে না Appএবং Messenger! এবং আমরা ইতিমধ্যেই এটিকে উত্তরাধিকারসূত্রে তৈরি করেছি Messengerএবং এটিকে ক্লাসে যুক্ত করেছি Client। কিন্তু Telegramক্লাস সহজেই উভয় ইন্টারফেস বাস্তবায়ন করতে পারেন! Clientতদনুসারে, আমরা ক্লাসটিকে একটি Telegramবস্তু হিসাবে দিতে পারি Messengerএবং আমরা এটিকে Smartphoneএকটি হিসাবে ক্লাসে দিতে পারি App। আপনি এটি কীভাবে করবেন তা এখানে:

public class Telegram implements Application, Messenger {

    // ...methods
}

public class Client {

    private Messenger messenger;

    public Client() {
        this.messenger = new Telegram();
    }
}


public class Smartphone {

    private Application application;

    public Smartphone() {
        this.application = new Telegram();
    }
}
এখন আমরা Telegramক্লাস ব্যবহার করছি যেভাবে আমরা চাই। কিছু জায়গায়, এটি একটি হিসাবে কাজ করে App। অন্যান্য জায়গায়, এটি একটি হিসাবে কাজ করে Messenger। আপনি অবশ্যই ইতিমধ্যে লক্ষ্য করেছেন যে ইন্টারফেস পদ্ধতিগুলি সর্বদা 'খালি', অর্থাৎ তাদের কোন বাস্তবায়ন নেই। এর কারণ সহজ: ইন্টারফেস আচরণ বর্ণনা করে, কিন্তু এটি বাস্তবায়ন করে না। 'ইন্টারফেসটি বাস্তবায়ন করে এমন সমস্ত বস্তুকে CanSwimঅবশ্যই সাঁতার কাটতে সক্ষম হতে হবে': ইন্টারফেসটি আমাদেরকে এটাই বলে। মাছ, হাঁস এবং ঘোড়া যেভাবে সাঁতার কাটে তা Fish, Duck, এবং এর জন্য একটি প্রশ্নHorseক্লাস, ইন্টারফেস নয়। টিভির জন্য যেমন চ্যানেল পরিবর্তন করা একটি কাজ। রিমোট আপনাকে এটির জন্য একটি বোতাম দেয়। যাইহোক, জাভা 8 - ডিফল্ট পদ্ধতিতে একটি আকর্ষণীয় সংযোজন উপস্থিত হয়েছে। উদাহরণস্বরূপ, আপনার ইন্টারফেসে 10টি পদ্ধতি রয়েছে। তাদের মধ্যে 9 টির বিভিন্ন শ্রেণিতে বিভিন্ন বাস্তবায়ন রয়েছে, তবে একটি সবার জন্য একইভাবে প্রয়োগ করা হয়েছে। পূর্বে, জাভা 8 এর আগে, ইন্টারফেস পদ্ধতির কোন বাস্তবায়ন ছিল না: কম্পাইলার অবিলম্বে একটি ত্রুটি দিয়েছিল। এখন আপনি এই মত কিছু করতে পারেন:

public interface CanSwim {

   public default void swim() {
       System.out.println("Swim!");
   }

   public void eat();

   public void run();
}
কীওয়ার্ড ব্যবহার করে default, আমরা একটি ডিফল্ট বাস্তবায়ন সহ একটি ইন্টারফেস পদ্ধতি তৈরি করেছি। আমাদের অন্য দুটি পদ্ধতির জন্য আমাদের নিজস্ব বাস্তবায়ন প্রদান করতে হবে — eat()এবং run()— যে সমস্ত ক্লাস বাস্তবায়ন করে CanSwim। আমাদের পদ্ধতির সাথে এটি করার দরকার নেই swim(): প্রতিটি ক্লাসে বাস্তবায়ন একই হবে। যাইহোক, আপনি ইতিমধ্যেই অতীতের কাজগুলিতে ইন্টারফেস জুড়ে এসেছেন, এমনকি আপনি লক্ষ্য না করলেও :) এখানে একটি উজ্জ্বল উদাহরণ: কেন জাভাতে ইন্টারফেস প্রয়োজনীয় - 2আপনি Listএবং Setইন্টারফেসের সাথে কাজ করেছেন! আরও স্পষ্টভাবে, আপনি তাদের বাস্তবায়নের সাথে কাজ করেছেন — ArrayList, LinkedList, HashSet, ইত্যাদি। একই চিত্র স্পষ্টভাবে একটি উদাহরণ দেয় যেখানে একটি ক্লাস একই সময়ে একাধিক ইন্টারফেস প্রয়োগ করে। উদাহরণস্বরূপ, এবং LinkedListপ্রয়োগ করেListDeque(ডাবল-এন্ডেড সারি) ইন্টারফেস। আপনি ইন্টারফেসের সাথে পরিচিত Map, বা বরং, এর HashMapবাস্তবায়নের সাথে। যাইহোক, এই চিত্রটি একটি বৈশিষ্ট্য চিত্রিত করে: ইন্টারফেসগুলি অন্যান্য ইন্টারফেসের উত্তরাধিকারী হতে পারে। ইন্টারফেস SortedMapউত্তরাধিকারসূত্রে পাওয়া যায় Map, যখন Dequeউত্তরাধিকারসূত্রে পাওয়া যায় Queue। আপনি যদি ইন্টারফেসের মধ্যে সম্পর্ক দেখাতে চান তবে এটি প্রয়োজনীয়, যেখানে একটি ইন্টারফেস অন্যটির একটি বর্ধিত সংস্করণ। ইন্টারফেসের সাথে একটি উদাহরণ বিবেচনা করা যাক Queue। আমরা এখনো পর্যালোচনা করিনিQueues, কিন্তু এটি বরং সহজ এবং একটি দোকানে একটি সাধারণ সারি বা লাইনের মতো কাজ করে৷ আপনি শুধুমাত্র সারির শেষে আইটেম যোগ করতে পারেন, এবং শুধুমাত্র শুরু থেকে নিতে পারেন. কিছু সময়ে, উভয় প্রান্তে আইটেম যোগ করতে এবং নেওয়ার জন্য ডেভেলপারদের সারির একটি উন্নত সংস্করণ প্রয়োজন। তাই তারা একটি Dequeইন্টারফেস তৈরি করেছে, যা একটি ডাবল-এন্ডেড কিউ। এটিতে একটি সাধারণ সারির সমস্ত পদ্ধতি রয়েছে। সর্বোপরি, এটি ডাবল-এন্ডেড সারির মূল, তবে এটি নতুন পদ্ধতিও যুক্ত করে।
মন্তব্য
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION