ششمین شکل از انواع ارثبری: ارثبری رابطها (Interface Inheritance) در C#
در سلسله آموزشهای ارثبری در برنامهنویسی شیءگرا با C#، تاکنون با انواع مختلفی از ارثبری مانند تکپایه، چندسطحی، سلسلهمراتبی و ترکیبی آشنا شدهایم. حالا در ششمین و آخرین بخش از این مجموعه، به سراغ یکی از مهمترین و کاربردیترین مفاهیم در C# میرویم: ارثبری رابطها (Interface Inheritance) این نوع ارثبری به ما اجازه میدهد از قابلیتهای ارثبری چندگانه به شکلی امن و کنترلشده استفاده کنیم. بیایید با جزئیات ، این موضوع را بررسی کنیم.
ارثبری رابطها چیست؟
در زبان C#، برخلاف برخی زبانها مثل C++ که از ارثبری چندگانه برای کلاسها پشتیبانی میکنند، ارثبری چندگانه فقط از طریق رابطها (Interfaces) امکانپذیر است. رابطها قراردادهایی هستند که مشخص میکنند یک کلاس چه رفتارهایی باید داشته باشد، بدون اینکه پیادهسازی آن رفتارها را اجبار کنند. این ویژگی به برنامهنویسان اجازه میدهد انعطافپذیری بیشتری در طراحی سیستمهای خود داشته باشند.
مثال مفهومی در C#
برای درک بهتر، فرض کنید میخواهیم کلاسی برای یک اردک طراحی کنیم که هم بتواند راه برود و هم شنا کند. اینجاست که ارثبری رابطها به کار میآید:
public interface IWalkable
{
void Walk();
}
public interface ISwimmable
{
void Swim();
}
public class Duck : IWalkable, ISwimmable
{
public void Walk() => Console.WriteLine("Walking...");
public void Swim() => Console.WriteLine("Swimming...");
}
class Program
{
static void Main()
{
Duck duck = new Duck();
duck.Walk(); // خروجی: Walking...
duck.Swim(); // خروجی: Swimming...
}
}
در این مثال:
رابط IWalkable متد Walk را تعریف میکند.
رابط ISwimmable متد Swim را تعریف میکند.
کلاس Duck هر دو رابط را پیادهسازی میکند و به این ترتیب از ارثبری چندگانه رابطها استفاده میکند.
نکات کلیدی در ارثبری رابطها
برای استفاده صحیح از این نوع ارثبری، باید به چند نکته مهم توجه کنیم:
ارثبری یگانه برای کلاسها: در C#، یک کلاس فقط میتواند از یک کلاس دیگر ارث ببرد (Single Inheritance). این محدودیت برای جلوگیری از پیچیدگیهای ناخواسته طراحی شده است.
ارثبری چندگانه با رابطها: برخلاف کلاسها، یک کلاس میتواند چندین رابط را پیادهسازی کند. این ویژگی به ما اجازه میدهد رفتارهای متنوعی را به یک کلاس اضافه کنیم.
مسئله الماس (Diamond Problem): در ارثبری چندگانه کلاسها (که در C# پشتیبانی نمیشود)، اگر دو کلاس والد یک متد یکسان را از یک پایه مشترک ارث ببرند، ابهام ایجاد میشود (به این مشکل، مسئله الماس میگویند). رابطها این مشکل را ندارند، زیرا فقط تعریف متد را ارائه میدهند و پیادهسازی بر عهده کلاس است.
اصل جایگزینی لیسکوف (Liskov Substitution Principle): در طراحی ارثبری، باید اطمینان حاصل کنیم که هر کلاس فرزند بتواند بدون تغییر رفتار مورد انتظار، جایگزین کلاس والد شود. این اصل به خصوص در استفاده از رابطها اهمیت دارد تا انسجام سیستم حفظ شود.
مزایا و کاربردها
ارثبری رابطها به ما امکان میدهد:
کد را ماژولار و قابلتست کنیم.
وابستگیها را کاهش دهیم (مثلاً با استفاده از تزریق وابستگی).
از الگوهای طراحی مثل Strategy یا Factory به شکلی تمیز استفاده کنیم.
نتیجهگیری
ارثبری رابطها به عنوان ششمین و آخرین شکل از انواع ارثبری در این سلسله آموزشها، یکی از قدرتمندترین ابزارهای C# برای طراحی سیستمهای منعطف و قابلگسترش است. در حالی که محدودیت ارثبری یگانه برای کلاسها ما را به نظم و سادگی تشویق میکند، رابطها دریچهای به سوی انعطافپذیری و چندمنظوره بودن باز میکنند. دفعه بعد که در حال طراحی یک پروژه هستید، به این فکر کنید که چگونه میتوانید از رابطها برای بهبود ساختار کد خود استفاده کنید. با این دانش، حالا آمادهاید تا ارثبری را در C# به شکلی حرفهای به کار ببرید!
توضیح راجع به سینتکس کد
این شیوه نوشتن کد که از عملگر => استفاده میکند، به نام Expression-Bodied Method شناخته میشود و در C# 6.0 معرفی شده است. این روش به شما اجازه میدهد متدهای تکخطی را به شکلی مختصر و خوانا بنویسید. به جای استفاده از بلوک {} و دستور return (در صورت نیاز)، میتوانید از => برای تعریف مستقیم بدنه متد استفاده کنید. برای مثال،
public void Walk() => Console.WriteLine("Walking...");
معادل
public void Walk()
{
Console.WriteLine("Walking...");
}
است، اما کوتاهتر و تمیزتر. این سبک معمولاً برای متدهای ساده و بدون منطق پیچیده استفاده میشود. برای بخاطر سپاری راحت آن می توانید آن را شبیه به حالتی در نظر بگیرید که یک جمله شرطی فقط یک عمل در پی دارد( بدون هیچ منطق و یا کد اضافی) در چنین حالتی همانطور که شاید می دانستید از آکولاد استفاده نمی کنیم.
if (x > 0) Console.WriteLine("عدد مثبت است");
البته اشتباه نشود عملگر => برای متدها بکار می رود و مثالی که زدم فقط برای بخاطر سپردن مطلب بود