দ্রুত তুলনা
| বিষয় | Abstract Class | Interface |
| প্রকৃতি | ক্লাস (ইনস্ট্যান্সিয়েট করা যায় না) | কন্ট্রাক্ট (শুধু সিগনেচার) |
| ইমপ্লিমেন্টেশন | হ্যাঁ (কংক্রিট + অ্যাবস্ট্রাক্ট মেথড) | C# 8.0 前: না; C# 8.0+: ডিফল্ট ইমপ্লিমেন্টেশন |
| ইনহেরিট্যান্স | সিঙ্গল (একটি বেস ক্লাস) | মাল্টিপল (একাধিক ইন্টারফেস) |
| কনস্ট্রাক্টর | হ্যাঁ (ডেরাইভড ক্লাস কল করে) | না |
| ফিল্ড/স্টেট | হ্যাঁ (ইনস্ট্যান্স/স্ট্যাটিক ফিল্ড) | না (C# 8.0+: static ফিল্ডও থাকতে পারে) |
| অ্যাক্সেস মডিফায়ার | সব (public, private, protected...) | C# 8.0 前: শুধু public; C# 8.0+: সব |
| পারফরম্যান্স | দ্রুত (ডাইরেক্ট কল, ভার্চুয়াল ডিসপ্যাচ) | অপেক্ষাকৃত ধীর (ইন্টারফেস ডিসপ্যাচ) |
| উদ্দেশ্য | "Is-a" রিলেশনশিপ, শেয়ার্ড কোড/স্টেট | "Can-do" ক্যাপাবিলিটি, পলিমরফিজম |
Abstract Class উদাহরণ
public abstract class Animal {
// শেয়ার্ড স্টেট
public string Name { get; set; }
public int Age { get; set; }
// কনস্ট্রাক্টর
protected Animal(string name, int age) {
Name = name;
Age = age;
}
// কংক্রিট মেথড (শেয়ার্ড লজিক)
public void Eat() {
Console.WriteLine($"{Name} is eating...");
}
// অ্যাবস্ট্রাক্ট মেথড (বাধ্যতামূলক ওভাররাইড)
public abstract void MakeSound();
// ভার্চুয়াল মেথড (অপশনাল ওভাররাইড)
public virtual void Sleep() {
Console.WriteLine($"{Name} is sleeping");
}
}
public class Dog : Animal {
public Dog(string name, int age) : base(name, age) { }
public override void MakeSound() {
Console.WriteLine($"{Name} says: Woof!");
}
public override void Sleep() {
Console.WriteLine($"{Name} sleeps in a dog bed");
}
}
Interface উদাহরণ (C# 8.0+ ফিচারসহ)
public interface IAnimal {
// প্রপার্টি (নন-ইমপ্লিমেন্টেড)
string Name { get; set; }
int Age { get; set; }
// মেথড সিগনেচার
void MakeSound();
// Default implementation (C# 8.0+)
void Eat() {
Console.WriteLine($"{Name} is eating...");
}
// Static members (C# 8.0+)
static int Count { get; set; }
static void ResetCount() => Count = 0;
// Private helper (C# 8.0+)
private void Log(string msg) => Console.WriteLine($"[LOG] {msg}");
}
public class Cat : IAnimal {
public string Name { get; set; }
public int Age { get; set; }
public void MakeSound() {
Console.WriteLine($"{Name} says: Meow!");
}
// Eat() ইনহেরিট হয় (ডিফল্ট ইমপ্লিমেন্টেশন)
}
মাল্টিপল ইনহেরিট্যান্স: Interface-এ সম্ভব, Abstract Class-এ নয়
// ✅ Interface: মাল্টিপল ইমপ্লিমেন্টেশন
public class FlyingFish : IFly, ISwim, IAnimal {
public void Fly() { ... }
public void Swim() { ... }
public void MakeSound() { ... }
}
// ❌ Abstract Class: শুধু একটা
// public class Impossible : Animal, Mammal { } // Error
// ✅ কিন্তু Interface + Abstract Class কম্বাইন করা যায়
public class Bat : Animal, IFly { // Animal = abstract class, IFly = interface
public override void MakeSound() => Console.WriteLine("Squeak!");
public void Fly() => Console.WriteLine("Flapping wings");
}
কোনটি কখন ব্যবহার করবেন?
✅ Abstract Class বেছে নিন যখন:
- ক্লাসগুলোর কমন বেস স্টেট/বিহেভিয়ার আছে (DRY)
- "Is-a" রিলেশনশিপ (Dog is an Animal)
- নন-পাবলিক মেম্বার দরকার (protected helper, private field)
- কনস্ট্রাক্টর দিয়ে ইনিশিয়ালাইজেশন কন্ট্রোল করতে চান
- ভার্সনিং: ভবিষ্যতে মেথড যোগ করলে ডেরাইভড ক্লাস ব্রেক হয় না (ডিফল্ট ইমপ্লিমেন্টেশন দিয়ে)
✅ Interface বেছে নিন যখন:
- "Can-do" ক্যাপাবিলিটি সংজ্ঞায়িত করতে (ISerializable, IComparable, IDisposable)
- মাল্টিপল ইমপ্লিমেন্টেশন দরকার
- স্ট্রাক্ট (struct) ইমপ্লিমেন্ট করবে (struct ইনহেরিট করতে পারে না)
- লুজ কাপলিং, ডিপেন্ডেন্সি ইনভারশন (DI), টেস্টিং (Mocking)
- স্মল, ফোকাসড কন্ট্রাক্ট (ISP - Interface Segregation Principle)
C# 8.0+ Interface Enhancements
- Default implementation — ব্রেকিং চেঞ্জ ছাড়া নতুন মেথড যোগ
- Static members — হেল্পার, ফ্যাক্টরি মেথড
- Private/Protected members — এনক্যাপসুলেশন
- Properties with accessors
সিদ্ধান্ত গাইড
প্রশ্ন ১: কি কমন স্টেট/লজিক শেয়ার করতে হবে?
হ্যাঁ → Abstract Class (বা Base Class + Interface)
না → প্রশ্ন ২
প্রশ্ন ২: কি মাল্টিপল টাইপ এই বিহেভিয়ার শেয়ার করবে?
হ্যাঁ → Interface
না → Abstract Class বা Concrete Class
প্রশ্ন ৩: কি Struct-এ ইমপ্লিমেন্ট করতে হবে?
হ্যাঁ → Interface (স্ট্রাক্ট ইনহেরিট করতে পারে না)