Inheritance

ধরো, তুমি একটি Animal Kingdom (প্রাণীজগৎ) নিয়ে ভাবছো।

এখানে Animal হলো একটি বেইস ক্লাস (Base Class)। অন্যদিকে Dog, Cat, Bird হলো এর সাবক্লাস (Subclasses)। পৃথিবীর সব প্রাণীরই কিছু সাধারণ বা কমন বৈশিষ্ট্য ও আচরণ থাকে, যেমন— খাওয়া (eat), ঘুমানো (sleep) এবং চলাফেরা করা (move)।

এখন, একটি কুকুরের (Dog) জন্য বা বিড়ালের (Cat) জন্য নতুন করে eat() বা sleep() মেথড লেখার কোনো প্রয়োজন নেই। সাবক্লাসগুলো সরাসরি Animal ক্লাস থেকে এই আচরণগুলো গ্রহণ করতে পারে এবং শুধু তার নিজস্ব নির্দিষ্ট আচরণ (যেমন কুকুরের ক্ষেত্রে bark()) যুক্ত করতে পারে।

সহজ কথায়: Inheritance (ইনহেরিটেন্স) হলো পূর্বের কোনো ক্লাসের বৈশিষ্ট্য (Properties) এবং আচরণ (Methods) পুনরায় ব্যবহার (Reuse) করে নতুন একটি ক্লাস তৈরি করার প্রক্রিয়া।

  • Parent Class / Superclass: যে ক্লাস থেকে বৈশিষ্ট্য ধার নেওয়া হয়, এটি সাধারণ বা কমন আচরণগুলো ডিফাইন করে।

  • Child Class / Subclass: যে ক্লাসটি বৈশিষ্ট্যগুলো ধার নেয়। এটি প্যারেন্টের সব কিছু ইনহেরিট করার পাশাপাশি নিজস্ব নতুন বৈশিষ্ট্যও যোগ করতে পারে।

Inheritance এর মূল সুবিধা ও প্রয়োজনীয়তা

  • Code Reusability (কোডের পুনর্ব্যবহার): একই কোড বারবার লিখতে হয় না, প্যারেন্ট ক্লাস থেকে সরাসরি ব্যবহার করা যায় (যেমন eat() বা sleep())।

  • Logical Hierarchy (লজিক্যাল গঠন): বাস্তব জগতের সাথে মিল রেখে অবজেক্টগুলোর মধ্যে একটি সুন্দর সম্পর্ক (Is-A relationship) তৈরি করা যায়।

  • Easy Maintenance (সহজ রক্ষণাবেক্ষণ): সাধারণ লজিকে কোনো পরিবর্তন আনতে হলে শুধু প্যারেন্ট ক্লাসে পরিবর্তন করলেই সব চাইল্ড ক্লাসে তা স্বয়ংক্রিয়ভাবে আপডেট হয়ে যায়।

  • Method Overriding (মেথড ওভাররাইডিং): ইনহেরিটেন্সের মাধ্যমেই পলিমরফিজম (Polymorphism) অর্জন করা সম্ভব হয়, যেখানে চাইল্ড ক্লাস প্যারেন্টের মেথডকে নিজের মতো কাস্টমাইজ করতে পারে।

Inheritance এর ধরন (Types of Inheritance)

অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিংয়ে ইনহেরিটেন্স মূলত কয়েক ভাগে বিভক্ত:

  1. Single Inheritance: একটি মাত্র প্যারেন্ট এবং একটি চাইল্ড ক্লাস।

  2. Multilevel Inheritance: চেইন বা স্তরে স্তরে ইনহেরিটেন্স (যেমন: Grandparent → Parent → Child)।

  3. Hierarchical Inheritance: একটি প্যারেন্ট ক্লাসের অধীনে একাধিক চাইল্ড ক্লাস।

  4. Multiple Inheritance: একটি চাইল্ড ক্লাসের একাধিক প্যারেন্ট থাকে (জাভাতে ক্লাসের মাধ্যমে এটি সরাসরি সাপোর্ট করে না, ইন্টারফেস লাগে। তবে পাইথনে ডিরেক্ট সাপোর্ট করে)।

নিচে জাভা এবং পাইথনের কোড এক্সাম্পল দিয়ে প্রতিটি বিস্তারিত আলোচনা করা হলো।

Single Inheritance (সিঙ্গেল ইনহেরিটেন্স)

এখানে একটি প্যারেন্ট ক্লাস থেকে একটি চাইল্ড ক্লাস তৈরি হয়।

Java Example:

// Parent Class
class Animal {
    protected String name;

    public void eat() {
        System.out.println(this.name + " is eating.");
    }

    public void sleep() {
        System.out.println(this.name + " is sleeping.");
    }
}

// Child Class
class Dog extends Animal {
    public void bark() {
        System.out.println(this.name + " is barking loudly.");
    }
}

public class SingleInheritanceDemo {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name = "Tommy";
        
        // Inherited methods
        dog.eat();    
        dog.sleep();  
        
        // Own specific method
        dog.bark();   
    }
}

সুবিধা: চাইল্ড ক্লাস Dog, প্যারেন্ট Animal এর কোড সরাসরি রিইউজ করছে এবং নিজের মেথড bark() যুক্ত করেছে।

Multilevel Inheritance (মাল্টিলেভেল ইনহেরিটেন্স)

এখানে ইনহেরিটেন্স ধাপে ধাপে বা লেভেল অনুযায়ী হয়। চাইল্ড ক্লাস তার প্যারেন্ট থেকে বৈশিষ্ট্য নেয়, আবার সেই প্যারেন্ট তার নিজের প্যারেন্ট থেকে বৈশিষ্ট্য নেয়।

Python Example:

# Grandparent Class
class Animal:
    def eat(self) -> None:
        print("Animal is eating.")

# Parent Class
class Mammal(Animal):
    def walk(self) -> None:
        print("Mammal is walking on land.")

# Child Class
class Dog(Mammal):
    def bark(self) -> None:
        print("Dog is barking: Woof Woof!")

if __name__ == "__main__":
    dog = Dog()
    
    # Inherited from Animal
    dog.eat()   
    
    # Inherited from Mammal
    dog.walk()  
    
    # Own method from Dog
    dog.bark()  

সুবিধা: একটি মাল্টি-লেভেল হায়ারার্কি তৈরি হয়, যেখানে আচরণগুলো ধাপে ধাপে নিচের দিকে প্রবাহিত হয়।

Hierarchical Inheritance (হায়ারার্কিক্যাল ইনহেরিটেন্স)

যখন একটি মাত্র প্যারেন্ট ক্লাসকে একাধিক চাইল্ড ক্লাস ইনহেরিট করে।

Java Example:

// Common Parent Class
class Vehicle {
    public void start() {
        System.out.println("Vehicle engine has started.");
    }
}

// Child Class 1
class Car extends Vehicle {
    public void openTrunk() {
        System.out.println("Car trunk is now open.");
    }
}

// Child Class 2
class Bike extends Vehicle {
    public void kickStart() {
        System.out.println("Bike is kick-started.");
    }
}

public class HierarchicalDemo {
    public static void main(String[] args) {
        Car car = new Car();
        car.start();      // Inherited from Vehicle
        car.openTrunk();  // Car's own method

        Bike bike = new Bike();
        bike.start();     // Inherited from Vehicle
        bike.kickStart(); // Bike's own method
    }
}

সুবিধা: একাধিক চাইল্ড ক্লাস (যেমন Car এবং Bike) তাদের কমন আচরণ (যেমন start()) একটি মাত্র জায়গা থেকে শেয়ার করে।

Multiple Inheritance (মাল্টিপল ইনহেরিটেন্স)

মাল্টিপল ইনহেরিটেন্সে একটি চাইল্ড ক্লাস একাধিক প্যারেন্ট ক্লাস থেকে বৈশিষ্ট্য গ্রহণ করে।

  • পাইথনে সরাসরি একাধিক ক্লাস ইনহেরিট করা যায়।

  • জাভাতে "Diamond Problem" (একই নামের মেথড একাধিক প্যারেন্টে থাকলে কনফ্লিক্ট হয়) এড়াতে ক্লাসের মাধ্যমে মাল্টিপল ইনহেরিটেন্স অ্যালাউ করা হয় না। এর বদলে জাভাতে Interface ব্যবহার করে এটি অর্জন করা হয়।

Python Example (Direct Multiple Inheritance):

class Flyable:
    def fly(self) -> None:
        print("Entity is flying in the sky.")

class Swimmable:
    def swim(self) -> None:
        print("Entity is swimming in the water.")

# Duck inherits from both Flyable and Swimmable
class Duck(Flyable, Swimmable):
    def quack(self) -> None:
        print("Duck is quacking.")

if __name__ == "__main__":
    duck = Duck()
    duck.fly()   # From Flyable
    duck.swim()  # From Swimmable
    duck.quack() # Own method

Java Example (Multiple Inheritance via Interfaces):

// Interface 1
interface Flyable {
    void fly();
}

// Interface 2
interface Swimmable {
    void swim();
}

// Class implements multiple interfaces
class Duck implements Flyable, Swimmable {
    @Override
    public void fly() {
        System.out.println("Duck is flying using its wings.");
    }

    @Override
    public void swim() {
        System.out.println("Duck is swimming in the pond.");
    }
}

public class MultipleInheritanceDemo {
    public static void main(String[] args) {
        Duck duck = new Duck();
        duck.fly();
        duck.swim();
    }
}

সুবিধা: একটি ক্লাস একই সাথে একাধিক সম্পূর্ণ ভিন্ন ধরনের আচরণ (Behavior) বা বৈশিষ্ট্য ধারণ করতে পারে, যা সিস্টেমকে অনেক বেশি ফ্লেক্সিবল করে তোলে।