در این پست که چهارمین پست از سری مجموعه آموزش انواع ارثبری می باشد ، استفاده از اینترفیس به عنوان جایگزینی برای ارثبری چندگانه را شرح می دهیم .
در سیشارپ، ارثبری مستقیم یک کلاس فرزند از چندین کلاس والد
(Multiple Inheritance) پشتیبانی نمیشود. اما راهحل بهتری به نام اینترفیس (Interface) وجود دارد که نه تنها این محدودیت را برطرف میکند، بلکه انعطافپذیری و طراحی بهتری را به برنامهنویسی شیءگرا اضافه میکند. در این پست، به بررسی این جایگزین و مزایای آن میپردازیم.
الف - تعریف اینترفیسهای مستقل
هر اینترفیس یک رفتار یا قابلیت خاص را تعریف میکند و به عنوان یک قرارداد (Contract) عمل میکند که کلاسها باید آن را پیادهسازی کنند. برای مثال:
public interface ISwimmable
{
void Swim();
}
public interface IFlyable
{
void Fly();
}
ب - پیادهسازی چندین اینترفیس در یک کلاس
برخلاف ارثبری کلاسها که محدود به یک والد است، یک کلاس میتواند همزمان چندین اینترفیس را پیادهسازی کند :
public class Duck : ISwimmable, IFlyable
{
public void Swim()
{
Console.WriteLine("شنا کردن در آب");
}
public void Fly()
{
Console.WriteLine("پرواز در آسمان");
}
}
ج - استفاده از چندوجهی (Polymorphism) با اینترفیسها
اینترفیسها امکان استفاده چندوجهی را فراهم میکنند. میتوانید یک شیء را هم به عنوان نوع کلاس خودش و هم به عنوان نوع اینترفیس استفاده کنید:
Duck duck = new Duck();
duck.Swim(); // خروجی: شنا کردن در آب
duck.Fly(); // خروجی: پرواز در آسمان
// استفاده به عنوان نوع اینترفیس
ISwimmable swimmer = duck;
swimmer.Swim(); // خروجی: شنا کردن در آب
مقایسه ارثبری کلاسها و اینترفیسها
برای درک بهتر تفاوتها، جدول زیر را ببینید:
ویژگی |
ارثبری کلاس |
اینترفیس |
تعداد والدین |
فقط یک کلاس |
نامحدود |
پیادهسازی پیشفرض |
دارد |
ندارد (تا C# 7) |
فیلدها |
پشتیبانی میشود |
پشتیبانی نمیشود |
متدهای Concrete |
دارد |
فقط متدهای Abstract |
استفاده اصلی |
اشتراکگذاری پیادهسازی |
اشتراکگذاری رفتار |
توجه: از C# 8 به بعد، اینترفیسها میتوانند متدهای پیشفرض داشته باشند، اما این موضوع خارج از بحث فعلی است.
د - مثال پیشرفته : ترکیب کلاس پایه و اینترفیسها
میتوانید از یک کلاس پایه برای اشتراکگذاری پیادهسازی و از اینترفیسها برای افزودن رفتارهای خاص استفاده کنید:
public class Animal // کلاس پایه
{
public void Eat()
{
Console.WriteLine("غذا خوردن");
}
}
public class Duck : Animal, ISwimmable, IFlyable
{
public void Swim()
{
Console.WriteLine("شنا کردن");
}
public void Fly()
{
Console.WriteLine("پرواز کردن");
}
}
// استفاده
Duck duck = new Duck();
duck.Eat(); // خروجی: غذا خوردن (از Animal)
duck.Swim(); // خروجی: شنا کردن (از ISwimmable)
duck.Fly(); // خروجی: پرواز کردن (از IFlyable)
چرا اینترفیسها بهتر از ارثبری چندگانه هستند؟
اجتناب از مسئله الماس (Diamond Problem):
در ارثبری چندگانه،
اگر دو کلاس والد متدی با نام یکسان داشته باشند، ابهام و تداخل ایجاد میشود.
اینترفیسها این مشکل را ندارند، زیرا فقط قرارداد تعریف میکنند و پیادهسازی به
عهده کلاس است.
انعطافپذیری بیشتر:
با اینترفیسها میتوانید
رفتارهای مختلف را به صورت ماژولار و مستقل به کلاسها اضافه کنید، بدون اینکه به
ساختار سلسلهمراتبی خاصی محدود شوید.
پایبندی به اصل تفکیک رابطها (ISP):
هر اینترفیس یک
مسئولیت مشخص و واحد دارد و کلاسها فقط رفتارهایی را پیادهسازی میکنند که
واقعاً به آنها نیاز دارند.
کاربرد عملی : فرض کنید در حال طراحی موجودات یک بازی هستید. میتوانید از اینترفیسها برای تعریف رفتارهای مختلف استفاده کنید :
public interface IAttackable
{
void Attack();
}
public interface IDamageable
{
void TakeDamage(int amount);
}
public class Dragon : Animal, IFlyable, IAttackable, IDamageable
{
public void Fly()
{
Console.WriteLine("پرواز اژدها");
}
public void Attack()
{
Console.WriteLine("حمله با آتش");
}
public void TakeDamage(int amount)
{
Console.WriteLine($"دریافت {amount} آسیب");
}
}
با این روش، میتوانید ترکیبهای نامحدودی از رفتارها را بدون پیچیدگیها و محدودیتهای ارثبری چندگانه ایجاد کنید.