Vivasoft-logo

পলিমরফিজমের প্রকার

পলিমরফিজমের প্রকারভেদ নিয়ে আলোচনা করার আগে নিচের বিষয়গুলো সম্পর্কে সুস্পষ্ট ধারনা থাকা উচিত:

  • মেথড ওভারলোডিং
  • অপারেটর ওভারলোডিং
  • মেথড ওভাররাইডিং

মেথড ওভারলোডিং

মেথড ওভারলোডিং হলো এমন একটি বৈশিষ্ট্য যার মাধ্যমে একই ক্লাসে একই নামের কিন্তু ভিন্ন প্যারামিটার সহ একাধিক মেথড তৈরি করা যায়।

এইখানে প্যারামিটারের ভিন্নতাটা তাদের সংখ্যা, টাইপ বা ক্রমের ভিত্তিতে হতে পারে।

মেথড সিগ্নেচার একই এবং রিটার্ন টাইপ ভিন্ন হলে কি হবে?

যেহেতু শুধুমাত্র রিটার্ন টাইপ কম্পাইলারের কোন মেথড কে কল করতে হবে সেটা নির্ধারণ করার জন্য পর্যাপ্ত না, সুতরাং কম্পাইলার এরোর দিবে। কেবল যদি উভয় মেথডের প্যারামিটার টাইপ অথবা সংখ্যা অথবা ক্রম আলাদা হয় (অর্থাৎ তাদের সিগনেচার ভিন্ন হয়) তাহলে এই মেথড ওভার লোডিং পসিবল। সুতরাং, মেথড ওভারলোডিং এর ক্ষেত্রে মেথডের রিটার্ন টাইপের কোন প্রভাব নেই।

মেথড ওভারলোডিং এর উদাহরণ

class Calculator {
    int add(int a, int b) {
        return a + b;
    }
    double add(double a, double b) {
        return a + b;
    }
    int add(int a, int b, int c) {
        return a + b + c;
    }
}
class Main {
  public static void main(String[] args) {
    Calculator myCalculator  = new Calculator ();  // Create a Calculator object
    System.out.println(“Sum of the two integer numbers = “+ myCalculator.add(3,5));
    System.out.println(“Sum of the two double numbers = “+ myCalculator.add(5.5,6.5));
    System.out.println(“Sum of the three integer numbers = “+ myCalculator.add(5,4,2));
  }
}

Output:

Sum of the two integer numbers = 8
Sum of the two double numbers = 12.0
Sum of the three integer numbers = 11

এই উদাহরণে, Calculator ক্লাসটিতে তিনটি ওভারলোডেড মেথড রয়েছে। প্রথম মেথডটি দুইটি ইন্টেজার টাইপের প্যারামিটার নেয়, দ্বিতীয় মেথডটি দুইটি ডাবল টাইপের প্যারামিটার নেয়, এবং তৃতীয় মেথডটি তিনটি ইন্টেজার টাইপের প্যারামিটার নেয়।

উপরের উদাহরণের কোড নিচে দেয়া হলঃ

using System;
class Calculator
{
    public int Add(int a, int b) {
        return a + b;
    }
    public double Add(double a, double b) {
        return a + b;
    }
    public int Add(int a, int b, int c) {
        return a + b + c;
    }
}
class Program
{
    static void Main(string[] args)
    {
        Calculator myCalculator = new Calculator();  // Create a Calculator object
        Console.WriteLine(“Sum of the two integer numbers = ” + myCalculator.Add(3, 5));
        Console.WriteLine(“Sum of the two double numbers = ” + myCalculator.Add(5.5, 6.5));
        Console.WriteLine(“Sum of the three integer numbers = ” + myCalculator.Add(5, 4, 2));
    }
}

Output:

Sum of the two integer numbers = 8
Sum of the two double numbers = 12.0
Sum of the three integer numbers = 11

অপারেটর ওভারলোডিং

অপারেটর ওভারলোডিং বলতে বোঝায়, অপারেন্ডের ডাটা টাইপের উপর নির্ভর করে একই অপারেটরের একাধিক রকম আচরণ (যেমন, +,-)। এইটা মনে রাখা গুরুত্বপূর্ণ যে, সব প্রোগ্রামিং ল্যাঙ্গুয়েজ অপারেটর ওভারলোডিং সাপোর্ট করে না, যেমন Java এবং Go। আবার C#, C++ ইত্যাদি অপারেটর ওভারলোডিং সাপোর্ট করে।

আমরা এখন C# এ অপারেটর ওভারলোডিং নিয়ে আলোচনা করব।

অপারেটর ওভারলোডিং এর মাধ্যমে পূর্বনির্ধারিত অপারেটরগুলো ইউজারের বানানো টাইপের (ক্লাস,স্ট্রাকচার) জন্য কিভাবে কাজ করবে তা আমরা পুনরায় নির্ধারণ করতে পারি, অর্থাৎ আমাদের বানানো টাইপের জন্য অপারেটরগুলো কিভাবে কাজ করবে তা আমরা নিজেদের মতো ইমপ্লিমেন্ট করতে পারি।

কোন অপারেটর গুলোকে ওভারলোড করা যায় এবং কোন অপারেটর গুলোকে ওভারলোড করা যায় না তার একটি তালিকা নিচে দেওয়া হলঃ

operator

C# এ অপারেটর ওভারলোডিং যেভাবে কাজ করেঃ

কোন কাস্টম টাইপের জন্য একটি অপারেটর ওভারলোড করতে সেই class বা struct এর মধ্যে একটি বিশেষ মেথড ডিফাইন করতে হয় যেটিতে operator কিওয়ার্ডটি থাকে এবং এরপরে অপারেটরটির নাম থাকে। মেথডেটির সিগনেচার অবশ্যই যে অপারেটর কে ওভারলোড করা হচ্ছে তার জন্য প্রত্যাশিত রিটার্ন টাইপ এবং প্যারামিটারের সাথে মিল থাকতে হবে। উদাহরণস্বরূপ ‘+’ অপারেটরকে ওভারলোড করার জন্য ‘operator +’ নামে একটি মেথড লিখতে হবে। কাস্টম টাইপের সাথে যখন অপারেটরটি ব্যবহার করা হবে তখন মেথডেটির ভিতরের কাস্টম ইমপ্লিমেন্টেশন অনুযায়ী অপারেটরটি কাজ করবে।

নিচে C# এ অপারেটর ওভারলোডিং এর একটি সহজ উদাহরণ দেয়া হলো, উদাহরণে একটি কাস্টম ক্লাস ‘ComplexNumber’ ব্যবহার করা হয়েছেঃ

using System;
public class ComplexNumber
{
    public double Real { get; }
    public double Imaginary { get; }
    public ComplexNumber(double real, double imaginary)
    {
        Real = real;
        Imaginary = imaginary;
    }
    // Overload the + operator to add two complex numbers
    public static ComplexNumber operator +(ComplexNumber c1, ComplexNumber c2)
    {
        double realSum = c1.Real + c2.Real;
        double imaginarySum = c1.Imaginary + c2.Imaginary;
        return new ComplexNumber(realSum, imaginarySum);
    }
    // Overload the == operator to compare two complex numbers for equality
    public static bool operator ==(ComplexNumber c1, ComplexNumber c2)
    {
        return c1.Real == c2.Real && c1.Imaginary == c2.Imaginary;
    }
    // Overload the != operator to compare two complex numbers for inequality
    public static bool operator !=(ComplexNumber c1, ComplexNumber c2)
    {
        return !(c1 == c2);
    }
}
public class Program
{
    public static void Main(string[] args)
    {
        ComplexNumber c1 = new ComplexNumber(1.0, 2.0);
        ComplexNumber c2 = new ComplexNumber(3.0, 4.0);
        // Overloaded + operator
        ComplexNumber sum = c1 + c2;
        Console.WriteLine($”c1 + c2 = {sum}”);
        // Overloaded == and != operators
        Console.WriteLine($”c1 == c2: {c1 == c2}”);
        Console.WriteLine($”c1 != c2: {c1 != c2}”);
    }
}

Output:

c1 + c2 = 4 + 6i
c1 == c2: False
c1 != c2: True

এই উদাহরণে আমরা ‘ComplexNumber’ নামে একটি ক্লাস ডিফাইন করেছি যেটাতে real এবং imaginary অংশ রিপ্রেজেন্ট করার জন্য প্রোপারটি রয়েছে। আমরা ‘+’ অপারেটরকে ওভারলোড করেছি দুইটা কমপ্লেক্স নাম্বারকে যোগ করার জন্য, ‘==’ ও ‘!=’ অপারেটর ওভারলোড করেছি তাদের ইকুয়ালিটি কম্পেয়ার করার জন্য।

মেথড ওভাররাইডিং

মেথড ওভাররাইডিং ঘটে যখন একটি ক্লাস আরেকটি ক্লাস কে ইনহেরিট করে এবং সাবক্লাসে (চাইল্ড ক্লাস) তার প্যারেন্ট ক্লাসের মতো একই নাম, প্যারামিটার এবং রিটার্ন টাইপ সহ মেথড থাকে। অন্য কথায়, একটি সাবক্লাস যখন তার প্যারেন্ট ক্লাসে ডিক্লেয়ার করা একই সিগনেচারের একটি ম্যাথডকে নিজের মতো করে ইম্পলিমেন্ট করে তখন মেথড ওভাররাইডিং ঘটে।

Java এবং C# এ মেথড ওভাররাইডিং এর পার্থক্য

এটি জেনে রাখা গুরুত্বপূর্ণ যে, C# এ কোন একটা মেথডকে ওভাররাইড করতে হলে, সুপার ক্লাসে মেথডের সাথে ‘virtual’ কিওয়ার্ড টা ইউজ করতে হবে, এবং সাব ক্লাসে ‘override’ কিওয়ার্ড টা ইউজ করতে হবে।

virtual – এই কীওয়ার্ডটি সুপার ক্লাসের একটি মেথডকে সাব ক্লাস দ্বারা ওভাররাইড করার অনুমতি দেয়।

override – এটি নির্দেশ করে যে সাব ক্লাসের মেথডটি সুপার ক্লাসের মেথডকে ওভাররাইড করছে।

কিন্তু Java তে কোন ‘virtual’ কিওয়ার্ড নাই, মেথডগুলো বাই ডিফল্ট ভার্চুয়াল। C# এর মতো নন-ভার্চুয়াল মেথড তৈরি করা যায় না।

মেথড ওভাররাইডিং এর উদাহরণঃ

class Animal {
    void makeSound() {
        System.out.println(“Animal makes a sound”);
    }
}
class Dog extends Animal {
    void makeSound() {
        System.out.println(“Dog barks”);
    }
}
class Cat extends Animal {
    void makeSound() {
        System.out.println(“Cat meows”);
    }
}
class Main {
    public static void main(String[] args) {
        Animal myDog = new Dog();
        myDog.makeSound(); // Calls the makeSound() method of Dog
        Animal myCat = new Cat();
        myCat.makeSound(); // Calls the makeSound() method of Cat
    }
}

Output:

Dog barks
Cat meows

এই উদাহরণে, আমাদের Animal নামে একটি সুপারক্লাস আছে এবং দুটি সাবক্লাস আছে, Dog এবং Cat। প্রত্যেক সাবক্লাস তাদের প্যারেন্ট ক্লাস বা সুপারক্লাস এর makeSound মেথডটিকে ওভাররাইড করে নিজেদের মতো করে ইম্পলিমেন্ট করে। Main ক্লাসের main ম্যাথডে আমরা myDog এবং myCat নামে দুইটি Animal টাইপের রেফারেন্স তৈরি করেছি যেগুলি যথাক্রমে Dog এবং Cat অবজেক্টকে রেফার করে। যদিও উভয় রেফেরেন্সই Animal টাইপের, কিন্তু রানটাইমে অবজেক্ট এর টাইপের উপর নির্ভর করে সঠিক মেথডটিই কল হয়। অর্থাৎ রেফারেন্স Animal টাইপের হওয়ায় কম্পাইল টাইমে সে Animal এর makeSound মেথডকে পয়েন্ট করবে, কিন্তু অবজেক্ট Cat টাইপের হলে রানটাইমে সে Cat এর makeSound মেথডকে এক্সিকিউট করবে এবং অবজেক্ট Dog টাইপের হলে রানটাইমে সে Dog এর makeSound মেথডকে এক্সিকিউট করবে। এই জন্য এখানে মেথড ওভাররাইড/ডাইনামিক পলিমরফিজম হয়েছে। রেফারেন্স Cat টাইপ হলে সে কম্পাইল এবং রান – দুই টাইমেই Cat এর মেথডকে পয়েন্ট ও এক্সিকিউট করতো। তখন এটা ওভাররাইড হতো না।

উপরের উদাহরণের C# ভার্সন নিচে দেয়া হলঃ

using System;
class Animal
{
    public virtual void MakeSound() {
        Console.WriteLine(“Animal makes a sound”);
    }
}
class Dog : Animal
{
    public override void MakeSound() {
        Console.WriteLine(“Dog barks”);
    }
}
class Cat : Animal
{
    public override void MakeSound() {
        Console.WriteLine(“Cat meows”);
    }
}
class Program
{
    public static void Main(string[] args) {
        Animal myDog = new Dog();
        myDog.MakeSound(); // Calls the MakeSound() method of Dog
        Animal myCat = new Cat();
        myCat.MakeSound(); // Calls the MakeSound() method of Cat
    }
}

Output:

Dog barks
Cat meows

C# এ virtual এবং override কিওয়ার্ডগুলো ব্যবহার না করলে কি ঘটবে?

এই প্রশ্নের উত্তর দিতে নিচে দুইটা সিনারিও নিয়ে আলোচনা করা যাক।

১. C# এ যদি override বা virtual কিওয়ার্ড ব্যবহার না করা হয়

বেইজ ক্লাসের একটি মেথডকে ওভাররাইড করার উদ্দেশ্যে সাবক্লাসে মেথডটি ইমপ্লিমেন্ট করার সময় যদি আমরা override কিওয়ার্ডটি ইউজ না করি, তাহলে C# কম্পাইলার সাবক্লাসের মেথডটিকে একটি নতুন মেথড হিসেবে বিবেচনা করবে, ওভাররাইড হিসেবে না। অর্থাৎ যখন আমরা সাবক্লাসটির ইনস্ট্যান্স দিয়ে মেথডটিকে কল করবো, এটি বেইজ ক্লাসের মেথডের আচরণকে প্রতিস্থাপন করবে না। সহজ ভাবে বলতে গেলে এক্ষেত্রে বেইজ ক্লাসের মেথডের ভিতরে লেখা কোডটি এক্সিকিউট হবে।

এটি ব্যাখ্যা করার জন্য এখানে একটি সহজ উদাহরণ দেয়া হলোঃ

using System;
class Animal
{
    public virtual void MakeSound()
    {
        Console.WriteLine(“Animal makes a sound”);
    }
}
class Cat: Animal
{
    // Without the ‘override’ keyword, this is not an override.
    public void MakeSound()
    {
        Console.WriteLine(“Cat meows”);
    }
}
class Program
{
    static void Main(string[] args)
    {
        Animal myCat = new Cat();
        myCat.MakeSound(); // Output: “Animal makes a sound.”
        Cat myRealCat = new Cat();
        myRealCat.MakeSound(); // Output: “Cat meows.”
    }
}

Output:

Animal makes a sound
Cat meows

এই উদাহরণে, Animal ক্লাসের MakeSound() মেথডটিতে virtual কিওয়ার্ডটি ব্যবহার করলেও Cat ক্লাসের MakeSound() মেথডটিতে override কিওয়ার্ডটি ব্যবহার করা হয়নি, তাই এটিকে ওভাররাইডের পরিবর্তে নতুন মেথড হিসেবে বিবেচনা করা হয়। যখন আমরা Cat এর একটি ইনস্ট্যান্স তৈরি করি এবং এতে MakeSound() কল করি, তখন এটি Cat ক্লাসে ডিফাইন করা মেথডটি এক্সিকিউট করে Animal ক্লাসেরটি নয়। এক্ষেত্রে আমরা যদি সুপার ক্লাসে virtual কিওয়ার্ডটি ব্যবহার যদি নাও করতাম, তাও প্রোগ্রামের এক্সিকিউশনে কোন পরিবর্তন হতো না।

২. C# এ যদি বেজক্লাসে virtual কিওয়ার্ড ইউজ না করা হয়

বেইজ ক্লাসে কোন মেথড ডিফাইন করার সময় যদি virtual কিওয়ার্ড না করা হয়, এটি বুঝায় যে মেথডটিকে ওভাররাইড করা যাবে না। এমতাবস্থায় যদি সাব ক্লাস override কিওয়ার্ডটি ব্যবহার করে তাহলে কম্পাইলেশন error দিবে।

ওভাররাইডিং এর ক্ষেত্রে সাবক্লাসের মেথড থেকে সুপার ক্লাসের মেথডকে কল করা

আমরা ইতিমধ্যে সাবক্লাস কিভাবে সুপার ক্লাসের মেথডকে ওভাররাইড করে তা উদাহরণসহ দেখেছি। আচ্ছা আমাদের যদি সুপার ক্লাসের মেথডটিকে ও কল করতে হয় তাহলে কিভাবে করব?

সেক্ষেত্রে আমরা Java তে super এবং C# এ base কিওয়ার্ড ব্যবহার করে সাবক্লাস থেকে সুপার ক্লাসের মেথডকে কল করতে পারি।

জাভা তে super কিওয়ার্ড ব্যবহারের উদাহরণ

class Animal {
  // method in the superclass
  void makeSound() {
    System.out.println(“Animal makes a sound”);
  }
}
// Cat inherits Animal
class Cat extends Animal {
  // overriding the eat() method
  void makeSound() {
    // call method of superclass
    super.makeSound();
    System.out.println(“Cat meows”);
  }
}
class Main {
  public static void main(String[] args) {
    Cat myCat = new Cat();
    // call the makeSound() method
    myCat.makeSound();
  }
}

Output:

Animal makes a sound
Cat meows

উপরের উদাহরণে, সুপার ক্লাস Animal এবং সাবক্লাস Cat উভয় ক্লাসেই makeSound() মেথডটি রয়েছে। নিচের স্টেটমেন্টটি লক্ষ্য করুন,

super.makeSound();

এখানে, আমরা super কিওয়ার্ডটি ব্যবহার করে সাবক্লাস Cat থেকে সুপারক্লাস Animal এর মেথডটিকে কল করেছি।

C# এ base কিওয়ার্ড ব্যবহারের উদাহরণ

using System;
class Animal
{
    public virtual void MakeSound() {
        Console.WriteLine(“Animal makes a sound”);
    }
}
class Cat : Animal
{
    // overriding method from Animal
    public override void MakeSound() {
         // call method from Animal class
        base.MakeSound();
        Console.WriteLine(“Cat meows”);
    }
}
class Program
{
    public static void Main(string[] args) {
        Cat myCat = new Cat();
        myCat.MakeSound();
    }
}

Output:

Animal makes a sound
Cat meows

উপরের উদাহরণে, সুপার ক্লাস Animal এবং সাবক্লাস Cat উভয় ক্লাসেই MakeSound() মেথডটি রয়েছে। নিচের স্টেটমেন্টটি লক্ষ্য করুন,

base.MakeSound();

এখানে, আমরা base কিওয়ার্ডটি ব্যবহার করে সাবক্লাস Cat থেকে সুপারক্লাস Animal এর মেথডটিকে কল করেছি।

পলিমরফিজমকে দুই প্রকারে ভাগ করা যায়ঃ

  1. স্ট্যাটিক বা কম্পাইল-টাইম পলিমরফিজম (Static or Compile Time)
  2. ডাইনামিক বা রানটাইম পলিমরফিজম (Dynamic Polymorphism or Runtime Polymorphism)

type

১. স্ট্যাটিক বা কম্পাইল-টাইম পলিমরফিজম

কম্পাইল-টাইম পলিমরফিজমে মেথড কলগুলো কম্পাইল টাইমে রিসলভ হয়। মেথড এবং অপারেটর ওভারলোডিং এর মাধ্যমে এই ধরনের পলিমরফিজম হয়ে থাকে। যদিও জাভা অপারেটর ওভারলোডিং সাপোর্ট করেনা, যেটি আমরা ইতিমধ্যে উপরে আলোচনা করেছি। কম্পাইল-টাইম পলিমরফিজমকে স্ট্যাটিক পলিমরফিজমও বলা হয়।

উপরের মেথড ওভারলোডিং এর উদাহরণটি কম্পাইল-টাইম পলিমরফিজমের একটি উদাহরণ। নিচে আরও একটি উদাহরণ দেয়া হলো।

কম্পাইল-টাইম পলিমরফিজমের উদাহরণঃ

class Shape {
    // Calculate area for a circle
    double area(double radius) {
        return 3.14 * radius * radius;
    }
    // Calculate area for a rectangle
    double area(double length, double width) {
        return length * width;
    }
}
public class Main {
    public static void main(String[] args) {
        Shape shapeCalculator = new Shape();
        // Calculate the area of a circle
        double circleArea = shapeCalculator.area(5.0);
        System.out.println(“Area of the circle: ” + circleArea);
        // Calculate the area of a rectangle
        double rectangleArea = shapeCalculator.area(4.0, 6.0);
        System.out.println(“Area of the rectangle: ” + rectangleArea);
    }
}

Output:

Area of the circle: 78.5
Area of the rectangle: 24.0

এই উদাহরণে, Shape ক্লাসটিতে দুইটি ওভারলোডেড area মেথড রয়েছে:

  1. প্রথম মেথডটি একটি double টাইপের radius প্যারামিটার নিয়ে বৃত্তের ক্ষেত্রফল হিসেব করে।
  2. দ্বিতীয় area মেথডটি দুটি প্যারামিটার নেয়: length ও width, এবং একটি আয়তক্ষেত্রের ক্ষেত্রফল গণনা করে।

Main ক্লাসের main মেথডে, আমরা Shape ক্লাসের একটি ইন্সটেন্স তৈরি করি এবং একটি বৃত্ত ও একটি আয়তক্ষেত্রের ক্ষেত্রফল গণনা করতে এর ওভারলোডেড area মেথডগুলো ব্যবহার করি।

উপরের উদাহরণের C# ভার্সন নিচে দেয়া হলঃ

using System;
class Shape
{
    // Calculate area for a circle
    public double Area(double radius)
    {
        return 3.14 * radius * radius;
    }
    // Calculate area for a rectangle
    public double Area(double length, double width)
    {
        return length * width;
    }
}
class MainClass
{
    public static void Main(string[] args)
    {
        Shape shapeCalculator = new Shape();
        // Calculate the area of a circle
        double circleArea = shapeCalculator.Area(5.0);
        Console.WriteLine(“Area of the circle: ” + circleArea);
        // Calculate the area of a rectangle
        double rectangleArea = shapeCalculator.Area(4.0, 6.0);
        Console.WriteLine(“Area of the rectangle: ” + rectangleArea);
    }
}

২. ডাইনামিক বা রানটাইম পলিমরফিজম

রান-টাইম পরিমরফিজম এর ক্ষেত্রে কোন মেথডটি কল হবে সেটি কম্পাইল-টাইমের পরিবর্তে রান-টাইমে ডায়নামিক্যালি নির্ধারণ করা হয়। তাই রান-টাইম পলিমরফিজম কে ডায়নামিক পলিমরফিজমও বলা হয়। রান টাইম পলিমরফিজম মেথড ওভার রাইডিং এবং ইন্টারফেস ইমপ্লিমেন্টেশনের মাধ্যমে অর্জন করা যায়।

মেথড ওভাররাইডিং হয় যখন একটি চাইল্ড বা সাব ক্লাসের তার প্যারেন্ট বা সুপার ক্লাসের মত একই নাম, প্যারামিটার এবং রিটার্ন টাইপ সহ একটি মেথড থাকে; তখন সেই মেথডটি সুপার ক্লাসের মেথডটিকে ওভাররাইড করে।

আমরা ইতিমধ্যে মেথড ওভার রাইডিং এর মাধ্যমে পলিমরফিজমের একটি উদাহরণ দেখেছি।

নিচে অ্যাবস্ট্রাক্ট ক্লাস ব্যবহার করে পলিমরফিজমের একটি উদাহরণ দেয়া হলঃ

অ্যাবস্ট্রাক্ট ক্লাসের মাধ্যমে পলিমরফিজমঃ

abstract class Shape {
    abstract double calculateArea();
}
class Rectangle extends Shape {
    private double width;
    private double height;
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    @Override
    double calculateArea() {
        return width * height;
    }
}
class Circle extends Shape {
    private double radius;
    public Circle(double radius) {
        this.radius = radius;
    }
    @Override
    double calculateArea() {
        return Math.PI * radius * radius;
    }
}
public class Main {
    public static void main(String[] args) {
        Shape shape1 = new Rectangle(5, 4);
        Shape shape2 = new Circle(3);
        System.out.println(“Area of Rectangle: ” + shape1.calculateArea()); // Output: Area of Rectangle: 20.0
        System.out.println(“Area of Circle: ” + shape2.calculateArea());    // Output: Area of Circle: 28.274333882308138
    }
}

Output:

Area of Rectangle: 20.0
Area of Circle: 28.274333882308138

এই Java উদাহরণে, আমরা Shape নামে একটি অ্যাবস্ট্রাক্ট ক্লাস তৈরি করেছি, এবং এর মধ্যে ‘calculateArea’ নামে একটি অ্যাবস্ট্র্যাক্ট মেথড ডিক্লেয়ার করেছি। Rectangle এবং Circle উভয় ক্লাসই Shape ক্লাস কে ইনহেরিট করে করে এবং ‘calculateArea’ মেথডটি নিজেদের মতো ইমপ্লিমেন্ট করে। মেইন মেথডে আমরা Rectangle এবং Circle উভয় ক্লাসের ইনস্টেন্স তৈরি করে কমন অ্যাবস্ট্রাক্ট ক্লাস ‘Shape’ এর মাধ্যমে তাদের ব্যবহার করি। এইভাবে ইন্টারফেস ব্যবহার করে পলিমরফিজম হয়ে থাকে।

উপরের উদাহরণের C# ভার্সন নিচে দেয়া হলঃ

using System;
abstract class Shape
{
    public abstract double CalculateArea();
}
class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }
    public Rectangle(double width, double height)
    {
        Width = width;
        Height = height;
    }
    public override double CalculateArea()
    {
        return Width * Height;
    }
}
class Circle : Shape
{
    public double Radius { get; set; }
    public Circle(double radius)
    {
        Radius = radius;
    }
    public override double CalculateArea()
    {
        return Math.PI * Radius * Radius;
    }
}
class Program
{
    static void Main()
    {
        Shape shape1 = new Rectangle(5, 4);
        Shape shape2 = new Circle(3);
        Console.WriteLine(“Area of Rectangle: ” + shape1.CalculateArea()); // Output: Area of Rectangle: 20
        Console.WriteLine(“Area of Circle: ” + shape2.CalculateArea());    // Output: Area of Circle: 28.274333882308138
    }
}

Output:

Area of Rectangle: 20.0
Area of Circle: 28.274333882308138

ইন্টারফেস ব্যবহার করে পলিমরফিজমঃ

interface Shape {
    double calculateArea();
}
class Rectangle implements Shape {
    private double width;
    private double height;
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    @Override
    public double calculateArea() {
        return width * height;
    }
}
class Circle implements Shape {
    private double radius;
    public Circle(double radius) {
        this.radius = radius;
    }
    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}
public class Main {
    public static void main(String[] args) {
        Shape shape1 = new Rectangle(5, 4);
        Shape shape2 = new Circle(3);
        System.out.println(“Area of Rectangle: ” + shape1.calculateArea()); // Output: Area of Rectangle: 20.0
        System.out.println(“Area of Circle: ” + shape2.calculateArea());    // Output: Area of Circle: 28.274333882308138
    }
}

Output:

Area of Rectangle: 20.0
Area of Circle: 28.274333882308138

এই Java উদাহরণে, আমরা একটি ‘calculateArea’ মেথড সহ ‘Shape’ নামে একটি ইন্টারফেস ডিফাইন করেছি। Rectangle এবং Circle উভয় ক্লাসই ইন্টারফেসটি ইম্পলিমেন্ট করে এবং ‘calculateArea’ মেথডটিও নিজেদের মতো ইমপ্লিমেন্ট করে। মেইন মেথডে আমরা উভয় ক্লাসের ইনস্টেন্স তৈরি করে ‘Shape’ ইন্টারফেস এর মাধ্যমে তাদের ব্যবহার করি। এইভাবে ইন্টারফেস ব্যবহার করে পলিমরফিজম হয়ে থাকে।

উপরের উদাহরণের C# ভার্সন নিচে দেয়া হলঃ

using System;
interface IShape
{
    double CalculateArea();
}
class Rectangle : IShape
{
    public double Width { get; set; }
    public double Height { get; set; }
    public Rectangle(double width, double height)
    {
        Width = width;
        Height = height;
    }
    public double CalculateArea()
    {
        return Width * Height;
    }
}
class Circle : IShape
{
    public double Radius { get; set; }
    public Circle(double radius)
    {
        Radius = radius;
    }
    public double CalculateArea()
    {
        return Math.PI * Radius * Radius;
    }
}
class Program
{
    static void Main()
    {
        IShape shape1 = new Rectangle(5, 4);
        IShape shape2 = new Circle(3);
        Console.WriteLine(“Area of Rectangle: ” + shape1.CalculateArea()); // Output: Area of Rectangle: 20
        Console.WriteLine(“Area of Circle: ” + shape2.CalculateArea());    // Output: Area of Circle: 28.274333882308138
    }
}

Output:

Area of Rectangle: 20
Area of Circle: 28.2743338823081