وراثت چند گانه قسمت ۱

در مطالب قبلی در مورد کلاسها برخی مطالب را نوشتم که شاید مفید بوده . تفاوت شی گرایی از دید برنامه نویسی و تحلیل را بررسی کردم .

یکی از ارکان مهم شی گرایی ،  وراثت است . البته قصد ندارم وراثت یگانه را بحث کنم . و دانستن این مبحث را به خواننده واگذار می کنم . بلکه انچه که می خواهم بحث کنم وراثت چند گانه است .

اگر از دید برنامه نویسی به وراثت نگاه کنیم ، شاید کمتر پیش بیاید که مجبور شوید کلاسی را ایجاد کنید که از بیش از یک کلاس دیگر ارث بری کند و معمولا وراثت از تنها یک کلاس است.

اما اگر از دیدی مفهومی و تحلیلی به وراثت نگاه کنیم متوجه می شویم که وراثت چندگانه از مهمترین ارکان اشیا موجود در اطراف ماست .

اکنون این سوال مطرح می شود که با توجه به واقعیت و حقیقت وجودی وراثت چندگانه ، پس چرا زبانهای امروزی مانند سی شارپ و جاوا از وراثت چند گانه بی بهره هستند .

 

لینک مطلب

در لینک بالا نقل قول مستقیم از Chris Brumme کرده. Chris کیه؟ یکی از اعضای تیم CLR مایکروسافت از سال 2003 بوده ، پس هر کسی نیست و همینجوری حرف نمیزنه.

 

بدلیل اینکه مایکروسافت قرار بود در ابتدا .net  را بر اساس چند زبان قرار دهد یعنی vb , c#  و غیره

اگر می خواست وراثت چند گانه را اضافه کند باید این امکان را به .net  اضافه می کرد یعنی خصوصیتی مشترک بین تمام زبانهای دات نت میشد ، این مسله باعث پیچیدگی زبانی مثل vb  می شد که با اهداف مایکروسافت همخوانی ندارد

لذا شرکت مایکروسافت مبنا را بر این قرار داد که از آنجا که اغلب کاربران کمتر به مباحث وراثت چند گانه نیاز دارند پس فعلا برای جلوگیری از پیچیدگیهای زبان ، از این امکان صرفنظر می کند. و فقط راههکار استفاده از  Interface    را بعنوان جایگزینی برای وراثت چند گانه مطرح می کند .

 

وراثت چند گانه با استفاده از interface

 

ما در واقع  با استفاده از interface   وراثت چندگانه را شبیه سازی می کنیم ، چرا که Interface  ها نمی توانند تمام ابعاد وراثت چندگانه را پیاده سازی کنند . بعدها بیشتر در این مورد مطلب می نویسم

اما فعلا وراثت را با استفاده از  Interface  توضیح می دهیم . همانطور که قبلا در مورد  Interface گفتم ، یک کلاس می تواند از بیش از یک Interface ارث بری کند و این شرط کافی برای وراثت چند گانه است .فرض کنید کلاس c  از دو کلاس  A , B   بصورت همزمان مانند شکل زیر ارث بری می کند

یعنی کد نویسی آن بصورت زیر باید باشد :


class A
}
m1();
}
class B
{
m2();
}
class C : A, B
{
m1();
m2();
}

اما در دنیای واقعی کدهای بالا صحیح نیست و امکان پذیر نیست ، چون ما از وراثت چندگانه به شکل بالا نمی تواینم استفاده کنیم پس باید ازیک کلاس مثلا  A  بصورت مستقیم ارث بری کنیم و برای کلاس بعدی یک  Interface  تعریف می کنیم تا از آن ارث بری کنیم یعنی کلاس C  ما باید مستقیما از کلاس A  و از Interface  کلاس  B  ارث بری کند شکل زیر را ببینید :




.

 

وکدهای مثال بالا:

class A
{
m1();
}

interface IB
{
m2();
}

class B : IB
{
m2();
}

class C : A, IB
{
B BObject;
m1();
m2() { BObject.m2();

}

در کد فوق ابتدا آینترفیس  IB  را تعریف می کنیم ، کلاس B  از اینترفیس IB  ارث بری می کند یعنی کلاس B  باید قوانین موجود در اینترفیس IB  را اعمال کند و در اکنون کلاس C  از کلاس A  بصورت معمولی و مستقیم ارث بری می کند اما در مورد کلاس B   ، ابتدا اینترفیس IB  را تعریف کردیم که کلاس c  از آن ارث بری کند سپس در تعریف کلاس C  متغیری از نوع کلاس B   تعریف می کنیم که به هنگام فراخوانی متدهای اینترفیس در حقیقت متدهای کلاس B  را فراخوانی می کنیم .