Lesson ৭ মিনিট পড়া

ইনহেরিট্যান্স এবং পলিমরফিজম (Inheritance & Polymorphism)

আগে থেকে যা তৈরি করা আছে, তার ওপর ভিত্তি করেই নতুন কিছু গড়ুন — এটি কোডের বংশ পরিচয় বা ফ্যামিলি ট্রি (family trees)

ইনহেরিট্যান্স কী? (What Is Inheritance?)

ইনহেরিট্যান্সকে (Inheritance) পারিবারিক রেসিপির খাতার (family recipe book) সাথে তুলনা করতে পারেন। আপনার দাদি হয়তো সাধারণ পাউরুটি বানানোর রেসিপি লিখে গিয়েছিলেন। আপনার মা সেই রেসিপি উত্তরাধিকার সূত্রে বা ইনহেরিট (inherit) করে পেয়েছিলেন এবং পাউরুটির সাথে দারুচিনি (cinnamon) মিশিয়ে দারুচিনির পাউরুটি তৈরি করেছিলেন। আপনি আবার আপনার মায়ের রেসিপি পেয়েছিলেন এবং সেই দারুচিনির পাউরুটির ওপর ফ্রস্টিং (frosting) বা মিষ্টি প্রলেপ দিয়ে দারুচিনি রোল (cinnamon rolls) তৈরি করেছিলেন। এখানে প্রতিটি প্রজন্মই আগের প্রজন্মের তৈরি করা রেসিপির ওপর ভিত্তি করে নতুন কিছু তৈরি করেছে, কাউকে পুরো রেসিপিটি একদম শুরু থেকে লিখতে হয়নি।

সি শার্পে (C#) একটি চাইল্ড ক্লাস (child class) (যাকে "ডিরাইভড (derived) ক্লাসও" বলা হয়) তার প্যারেন্ট ক্লাস (parent class) (বা "বেস (base) ক্লাস") থেকে সমস্ত প্রোপার্টি (properties) এবং মেথড (methods) ইনহেরিট করে বা পেয়ে থাকে। চাইল্ড ক্লাস চাইলে আগেরগুলোর সাথে নতুন কিছু যোগ করতে পারে অথবা পুরনো আচরণকে নিজের মতো করে পরিবর্তনও করে নিতে পারে।

সি শার্পে (C#) ইনহেরিট্যান্স বোঝাতে কোলন : ব্যবহার করা হয়: class Child : Parent

ব্যাসিক ইনহেরিট্যান্স (Basic Inheritance)

class Animal
{
public string Name { get; set; }
public int Legs { get; set; }
public Animal(string name, int legs)
{
Name = name;
Legs = legs;
}
public virtual string Speak() // virtual = children CAN override this
{
return "...";
}
public string Describe()
{
return $"{Name} has {Legs} legs";
}
}
class Dog : Animal // Dog inherits from Animal
{
public string Breed { get; set; }
// Call the parent constructor with 'base'
public Dog(string name, string breed) : base(name, 4)
{
Breed = breed;
}
public override string Speak() // override the parent's method
{
return "Woof!";
}
}
class Cat : Animal
{
public Cat(string name) : base(name, 4) { }
public override string Speak() => "Meow!";
}
var dog = new Dog("Rex", "Husky");
var cat = new Cat("Whiskers");
Console.WriteLine($"{dog.Describe()} — Breed: {dog.Breed}");
Console.WriteLine($"{dog.Name} says: {dog.Speak()}");
Console.WriteLine($"{cat.Describe()}");
Console.WriteLine($"{cat.Name} says: {cat.Speak()}");
Output
Rex has 4 legs — Breed: Husky
Rex says: Woof!
Whiskers has 4 legs
Whiskers says: Meow!

পলিমরফিজম — এক চেহারা, নানারকম রূপ (Polymorphism — One Interface, Many Forms)

পলিমরফিজম (Polymorphism) শুনতে একটি কঠিন শব্দ মনে হলেও এর মূল ধারণাটি বেশ সহজ: কোনো চাইল্ড বা শিশু অবজেক্টকে আপনি চাইলে তার প্যারেন্টের মতো করেও ব্যবহার করতে পারেন, আর এতে সব সময় সঠিক মেথডটিই কল বা রান হবে। একে এমন একটি রিমোট কন্ট্রোলের সাথে তুলনা করা যায়, যা যেকোনো ব্র্যান্ডের টিভির সাথেই কাজ করে — আপনি শুধু "volume up" বা ভলিউম বাড়ানোর বোতাম চাপবেন, আর প্রতিটি টিভি নিজের পদ্ধতি অনুযায়ী ভলিউম বাড়িয়ে নেবে।

এটি অবিশ্বাস্য রকমের একটি শক্তিশালী টুল। আপনি প্যারেন্ট ক্লাসের জন্য কোড লিখলেও সেটি নিজে থেকেই বা স্বয়ংক্রিয়ভাবে তার যেকোনো চাইল্ড ক্লাসের সাথে কাজ করবে — এমনকি সেসব চাইল্ড ক্লাসের সাথেও, যেগুলো হয়তো এখনও তৈরিই হয়নি!

পলিমরফিজম এবং অ্যাবস্ট্রাক্ট ক্লাসেস (Polymorphism & Abstract Classes)

// Abstract class — can't be instantiated, only inherited
abstract class Shape
{
public string Color { get; set; }
public Shape(string color) => Color = color;
// Abstract method — children MUST implement this
public abstract double Area();
// Regular method — children inherit this as-is
public string Label() => $"{Color} {GetType().Name}";
}
class Circle : Shape
{
public double Radius { get; set; }
public Circle(double radius, string color) : base(color)
=> Radius = radius;
public override double Area() => Math.PI * Radius * Radius;
}
class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public Rectangle(double w, double h, string color) : base(color)
{
Width = w;
Height = h;
}
public override double Area() => Width * Height;
}
// sealed = no one can inherit from this class
sealed class Square : Rectangle
{
public Square(double side, string color) : base(side, side, color) { }
}
// Polymorphism in action!
Shape[] shapes = {
new Circle(5, "Red"),
new Rectangle(4, 6, "Blue"),
new Square(3, "Green")
};
foreach (Shape shape in shapes)
{
// Each shape calculates area its own way!
Console.WriteLine($"{shape.Label()}: Area = {shape.Area():F2}");
}
Output
Red Circle: Area = 78.54
Blue Rectangle: Area = 24.00
Green Square: Area = 9.00

জরুরি কিওয়ার্ডগুলোর সারসংক্ষেপ (Key Keywords Summary)

  • virtual — "এই মেথডের চাইল্ডরা চাইলে একে ওভাররাইড (override) বা পরিবর্তন করতে পারে।"
  • override — "আমি আমার প্যারেন্টের দেওয়া কাজের পদ্ধতি বা ইমপ্লিমেন্টেশনকে (implementation) বাদ দিয়ে নিজের মতো একটি পদ্ধতি তৈরি করছি।"
  • abstract — "আমি এই মেথডের কোনো ইমপ্লিমেন্টেশন বা কাজের ধারা দিচ্ছি না। তবে আমাকে ব্যবহার করা প্রতিটি চাইল্ডকে অবশ্যই এটি ইমপ্লিমেন্ট করতে হবে বা বানিয়ে নিতে হবে।" এটি সাধারণত ক্লাস এবং মেথডের নামের আগে ব্যবহৃত হয়।
  • sealed — "আমাকে আর কেউ ইনহেরিট (inherit) করতে পারবে না বা আমি কাউকে আর কিছু দেব না।" এটি মূলত একটি পরিবারের বংশের শেষ হওয়ার মতো অবস্থা।
  • base — "আমার প্যারেন্ট ক্লাসের কোনো কনস্ট্রাক্টর (constructor) বা মেথডকে ডাকুন।" এটি অনেকটা আসল রেসিপিটি জানার জন্য দাদিকে ফোন করার মতো।
Note: 🧬 অ্যাবস্ট্রাক্ট (Abstract) বনাম ভার্চুয়াল (Virtual): যখন আপনি চান যে আপনার করা মেথডটি প্রতিটি চাইল্ড ক্লাস অবশ্যই (MUST) নিজেদের মতো ইমপ্লিমেন্ট করে নিক, তখন abstract মেথডটি ব্যবহার করবেন (যেমন Area() — যার মাধ্যমে প্রতিটি শেইপ বা আকৃতি আলাদা আলাদাভাবে নিজেদের জমির পরিমাণ বা ক্ষেত্রফল বের করে)। আর যখন আপনার তৈরি করা মেথডটি ডিফল্ট (default) হিসেবে ব্যবহার করার সুযোগ থাকে, কিন্তু চাইল্ড ক্লাসটি চাইলে নিজের মতো করে পরিবর্তনও করে নিতে পারে (CAN override), তখন virtual মেথডটি ব্যবহার করবেন।
চ্যালেঞ্জ

ছোট কুইজ

আপনি কি কোনো অ্যাবস্ট্রাক্ট ক্লাসের (abstract class) ইনস্ট্যান্স বা অবজেক্ট তৈরি করতে পারেন?
Classes & ObjectsInterfaces & Abstract Classes