মূল কন্টেন্টে যান
মডিউল 3 · 2-এর পাঠ 2কোর্সে 6/14~15 min
মডিউল পাঠ (2/2)

পলিমরফিজম এবং বিমূর্ত ক্লাস

পলিমরফিজম এবং বিমূর্ত ক্লাসগুলি হল উন্নত অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং ধারণা যা আমাদের নির্দিষ্ট বাস্তবায়নের থেকে স্বাধীন, নমনীয়, এক্সটেনসিবল কোড লিখতে দেয়।

পলিমরফিজম

পলিমরফিজম (অনেক রূপ) শব্দটি বিভিন্ন শ্রেণীর বস্তুকে একটি সাধারণ প্রকারের অন্তর্গত হিসাবে আচরণ করার ক্ষমতাকে বোঝায়। জাভাতে, একটি সুপারক্লাস রেফারেন্স ভেরিয়েবল তার যেকোনো সাবক্লাসের একটি বস্তুর রেফারেন্স সংরক্ষণ করতে পারে।

Java
class Animal {
    public void makeSound() {
        System.out.println("Verso...");
    }
}

class Dog extends Animal {
    public void makeSound() {
        System.out.println("Woof");
    }
}

class Cat extends Animal {
    public void makeSound() {
        System.out.println("Miao");
    }
}

পলিমারফিজমের জন্য ধন্যবাদ, আমরা এটি করতে পারি:

Java
Animal myAnimal1 = new Dog(); // Polymorphism
Animal myAnimal2 = new Cat(); // Polymorphism

myAnimal1.makeSound(); // Executes Dog's method (Woof)
myAnimal2.makeSound(); // Executes Cat's method (Miao)

কোন পদ্ধতি চালু করতে হবে তার সিদ্ধান্ত রানটাইমে (লেট বাইন্ডিং বা ডাইনামিক ডিসপ্যাচ) প্রকৃত বস্তুর উপর ভিত্তি করে নেওয়া হয়, রেফারেন্স ভেরিয়েবলের ধরনের নয়।

বিমূর্ত ক্লাস (abstract)

একটি বিমূর্ত শ্রেণী হল একটি শ্রেণী যা abstract কীওয়ার্ড দিয়ে চিহ্নিত করা হয় যা সরাসরি ইনস্ট্যান্ট করা যায় না (আপনি new MyAbstractClass() করতে পারবেন না)। এটি অন্যান্য শ্রেণীর জন্য একটি "আংশিক টেমপ্লেট" হিসাবে কাজ করে।

বিমূর্ত পদ্ধতি

একটি বিমূর্ত শ্রেণীতে বিমূর্ত পদ্ধতি থাকতে পারে: একটি বডি ছাড়াই ঘোষিত পদ্ধতি (কোন কোঁকড়া ধনুর্বন্ধনী বা কোড নেই), একটি সেমিকোলন দিয়ে শেষ হয়। উত্তরাধিকারসূত্রে প্রাপ্ত সমস্ত বিমূর্ত পদ্ধতি বাস্তবায়নের জন্য অ-বিমূর্ত উপশ্রেণীর প্রয়োজন।

Java
abstract class Shape {
    String color;

    // Abstract method (no body)
    public abstract double getArea();
}

class Circle extends Shape {
    double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    // Required to implement getArea
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

ডায়নামিক বাইন্ডিং / লেট বাইন্ডিং

রানটাইমে কোন পদ্ধতি চালাতে হবে তা কিভাবে জাভা জানে? এই প্রক্রিয়াটি লেট বাইন্ডিং (বা ডায়নামিক বাইন্ডিং) নামে পরিচিত। ওভারলোডিংয়ের বিপরীতে (যা কম্পাইল-টাইমে সমাধান করা হয়), কম্পাইলার জানে না কোন নির্দিষ্ট পদ্ধতিটি কার্যকর করা হবে। পরিবর্তে, এটি একটি জেনেরিক কল নির্দেশনা তৈরি করে। রানটাইমে, জাভা ভার্চুয়াল মেশিন (JVM) মেমরিতে প্রকৃত অবজেক্ট পরিদর্শন করে এবং সেই অবজেক্টের ক্লাসে সংজ্ঞায়িত পদ্ধতি বাস্তবায়নের আহ্বান জানায়।

বিমূর্ত ক্লাস এবং অনুপস্থিত বাস্তবায়ন

যদি একটি সাবক্লাস একটি বিমূর্ত শ্রেণী থেকে উত্তরাধিকারসূত্রে প্রাপ্ত হয়, তবে এর দুটি বিকল্প রয়েছে:

  1. সমস্ত বিমূর্ত পদ্ধতি প্রয়োগ করুন: এই ক্ষেত্রে, সাবক্লাসটি একটি সাধারণ (কংক্রিট) শ্রেণী হতে পারে এবং তা ইনস্ট্যান্ট করা যেতে পারে।
  2. নিজেকে বিমূর্ত ঘোষণা করুন: যদি সাবক্লাস সমস্ত উত্তরাধিকারসূত্রে পাওয়া বিমূর্ত পদ্ধতির জন্য একটি বাস্তবায়ন প্রদান না করে, তবে এটিকে abstract কীওয়ার্ড দিয়েও ঘোষণা করতে হবে।
Java
abstract class Animal {
    public abstract void makeSound();
}

// This class MUST be abstract because it does not implement makeSound()
abstract class Canine extends Animal {
    // Inherits makeSound() but does not implement it
}

নিজে চেষ্টা করে দেখুন

ব্যায়াম#java.m3.l2.e1
প্রচেষ্টা: 0লোড হচ্ছে...

আকৃতির একটি পরিবর্তনশীল s ঘোষণা করুন এবং পলিমারফিজম ব্যবহার করে এটিতে একটি নতুন সার্কেল অবজেক্ট বরাদ্দ করুন।

সম্পাদক লোড হচ্ছে...
ইঙ্গিত দেখান

বেস টাইপটিকে রেফারেন্স টাইপ হিসাবে ব্যবহার করতে `Shape s = new Circle();` লিখুন।

সমাধান 3 প্রচেষ্টার পরে উপলব্ধ

ব্যায়াম#java.m3.l2.e2
প্রচেষ্টা: 0লোড হচ্ছে...

আকৃতি ক্লাস বিমূর্ত করুন এবং বিমূর্ত পদ্ধতি যোগ করুন double getArea()। তারপর স্কোয়ার সম্পূর্ণ করুন যাতে এটি আকার প্রসারিত করে এবং getArea() রিটার্নিং সাইড * সাইড প্রয়োগ করে।

সম্পাদক লোড হচ্ছে...
ইঙ্গিত দেখান

আকারে `সর্বজনীন বিমূর্ত ডাবল getArea();` ঘোষণা করুন। স্কোয়ারে, `@Override public double getArea() { রিটার্ন সাইড * সাইড যোগ করুন; }`

সমাধান 3 প্রচেষ্টার পরে উপলব্ধ

ব্যায়াম#java.m3.l2.e3
প্রচেষ্টা: 0লোড হচ্ছে...

প্রধান পদ্ধতিতে 2.0 ব্যাসার্ধ সহ একটি বৃত্ত বস্তু এবং পার্শ্ব 3.0 সহ একটি বর্গাকার বস্তু ধারণকারী আকৃতির একটি বিন্যাস ঘোষণা করুন। তারপর, getArea() পদ্ধতি ব্যবহার করে প্রতিটি আকৃতির ক্ষেত্রফল প্রিন্ট করতে একটি লুপ (প্রতিটির জন্য বা জন্য) ব্যবহার করুন।

সম্পাদক লোড হচ্ছে...
ইঙ্গিত দেখান

`Shape[] শেপ = { new Circle(2.0), new Square(3.0) };` দিয়ে অ্যারে ডিক্লেয়ার করুন এবং `for (Shape s : shapes)` প্রিন্টিং `s.getArea()` ব্যবহার করে এর মধ্য দিয়ে লুপ করুন।

সমাধান 3 প্রচেষ্টার পরে উপলব্ধ