وراثت در سی شارپ
یکی از مهمترین مباحث سی شارپ یا بهتره بگم اکثر زبانهای برنامه نویسی مبحث ارث بری میباشد در هنگام ایجاد یک گروه به جای نوشتن اعضای جدید گروه وعملکردها عضو به طور کامل، برنامه نویس می تواند تعیین کند که گروه جدید باید اعضا را از یک گروه موجود بگیرد. این گروه موجود base class-گروه پایه نامیده می شود و گروه جدید به عنوان derived class -گروه مشتق-اشاره می شود.
به انگلیسی inheritance یعنی وراثت—یعنی در این مبحث چیزی بنام پدر وجود داره همچنین فرزند هم وجود داره و همه خصوصیات پدر رو فرزند به ارث میبره و هر انچه که پدر داره به فرزندش به ارث میرسه و در سی شارپ یه کلاس نمیتونه از چند تا کلاس ارث بری کنه
دو نوع ارث بری داریم
مستقیم Direct
و غیر مستقیم Indirect
همه کلاسها در صورت کلی از کلاس ابجکت بصورت غیر مستقیم ارث بری میکنند البته غیراز کلاسهایی که خود از هیچ کلاسی ارث بری نمیکنند
شرح وراثت
بطور مثال یه کلاس بنام parent و یه کلاس دیگه بنام child داریم و جهت ارث بری فرزند از والد جلو نام کلاس فرزند پس از دونقطه اسم کلاس اصلی رو مینویسیم توجه داشته باشید برای انتصاب کلاس بالاتر یا والد به کلاس پایین یا فرزند در وراثت با گذاشتن دونقطه یا کالن و سپس نوشتن نام کلاس بالاتر این کارو انجام داد
class Parent
{ }
class Child : Parent
{ }
کلاس- خصوصیات یا صفاتی را از کلاس دیگر به ارث میبرد. کلاسی که موجود است کلاس پایه یا کلاس مافوق و کلاسی که از کلاس پایه ایجاد میشود، کلاس مشتق یا کلاس فرعی نامیده میشود. هر کلاس مشتق میتواند فقط یک کلاس پایه داشته باشد ولی هر کلاس پایه میتواند چندین کلاس مشتق داشته باشد. بعبارت دیگر هر تعدادی از کلاسها میتوانند رفتارها و صفات یک کلاس خاص را به ارث ببرند. هر کلاس پایه میتواند مشتق یک کلاس پایه دیگر باشد و بدین ترتیب ، سلسله مراتبی از کلاس پایه ایجاد شود.
در بالای سلسله مراتب کلاس سی شارپ کلاس object قرار دارد، یعنی تمام کلاسهای سی شارپ، صفات و رفتارهای خود را از این کلاس به ارث میبرند. Objectدر این سلسله مراتب یک کلاس کلی است و رفتارها و صفاتی را تعریف میکند که توسط سایر کلاسهای موجود در کتابخانه سی شارپ به ارث برده میشوند. در سلسله مراتب کلاسها هر چه به طرف پایین حرکت کنیم، کلاسها برای منظور خاصی ایجاد میشوند.در سی شارپ وراثت چندگانه نداریم یعنی کلاسی نمیتواند بیش از یک کلاس بطور مستقیم مشتق شود.
هر شیءای از کلاس مشتق،شیءای از کلاس پایه آن کلاس مشتق نیز هست. اما اشیای کلاس پایه اشیایی از کلاس مشتق خود نیستند.
برای شفاف شدن موضوع یه مثال دیگه میزنم
ببینید کلاس والد ما کلاسی هست بنام میوه و کلاس فرزند یا کلاسی که ارث بری میکنه اسمشو میزاریم لیمو
class Mive
{my codes }
class Leemo : Mive
{ }
برای روشن شدن موضوع به شکل زیر توجه کنید
3تا کلاس داریم کلاس اولGrandfather
کلاس دومFather
کلاس سوم Child
به ترتیب فرزند از پدر و پدر از پدربزرگ ارث بری میکنند این یک شکل ساده از وراثت میباشد
اما یه property برای کلاس پدربزرگ ایجاد میکنیم و فیلدی از نوعint ایجاد میکنیم حال در کلاس child فیلد کلاس پدبزرگ رو فراخوانی مکنیم و میتونیم به خصوصیات داخل کلاس پدربزرگ دسترسی داشته باشیم مثلا در کلاس فوق که متغییرسنage-- تعریف شده است در کلاسchildاونو فراخانی میکنیم و میتونیم بهش مقدار بدیم
مثال زیر
اصلاحات
رابطه بین کلاس پدر و فرزند میشه specialization به معنی تخصیص
رابطه بین کلاس فرزند و پدر میشه Generalzition یعنی تعمیم
Upcasting
DownCasting
کست کردن یعنی تبدیل یک نوع به نوعی دیگر مثلا در تبدیل نوعint به longبصورتی که مشاهده میکنید خط اول و دوم بدون کست کردن هست ولی در خط سوم برای تبدیل نوع از کست کردن استفاده شده است
1. 1. int I;
2. Long lng=15;
3. I=(int)lng;
و یه مثال دیگه ما دو تا کلاس پدر و فرزند داریم
1. Class Father
2. {}
3. Class Child:Father
4. {}
حال از کلاس پدر و فرزند یه instance میسازیم
1. Father f =new Father();
2. Child c=New Child();
حال میتونیم کلاس پدر رو مساوی کلاس فرزند قرار بدیم
;F=C
به این عمل یعنی پروسه کست کردن کلاس فرزند به کلاس پدر رو میگیم upCasting
و برعکس اون یعنی کست کردن کلاس پدر در کلاس فرزند رو میگن DownCasting
اما در انجام عمل کست کردن کلاس فرزند به کلاس پدر کامپایلر خطا میگره و امکان implicite کردن منوع است برای تبدیل این عمل نوع کلاس فرزند مشخص بشه و بصورت explicite casting کلاس فرزند به کلاس پدر کست میشه
C=(child)f;
بحث constructor chaining
مقدمه
CONSTRUCTOR یعنی سازنده
constructor chaining زنجیره کانستراکتورها
اما توضیح مختصری در مورد کانستراکتور
کانستراکتور برای مقدار دهی اولیه فیلدها یا متد بکار میره مثلا هرزمان یک کلاس ساخته شد کانستراکتور(متدسازنده)ان کلاس فرخوانی میشود و یک کلاس ممکن است دارای چندین کانستراکت باشه و این کانسترکت به برنامه نویس امکان میده داده های یا مقایر پیش فرض رو تعیین کنند
یا به زبان ساده تر کانستراکتور متدی هم نام با کلاس است که وظیفه ساختن و برگرداندن نمونه جدید object از همون کلاس رو برعهده داره
در سی شارپ اگه برای کلاس کانسترکتوری ساخته نشه کامپایلر بصورت اتوماتیک یه کانستراکت بعنوان پیش فرض میسازه برای مطالعه بیشتر در مورد کانستراکت و یادگیری به فیلم اموزشی که استاد مهرداد نادری تهیه کردند مراجعه کنید
زمانیکه کلاس فرزند رو فراخوانی میکنیم بصورت خودکار کلاس پدر نیز در حافظه ساخته میشه یعنی سلسله مراتب کلا به این صورت ساخته میشن یعنی اگه کلاس بالایی پدربزرگ رو نیز داشته باشیم اونم ساخته میشه به علت اینکه زمانیکه یک کلاس ساخته میشه از کانستراکتور یک کلاس instance همون کلاس ساخته میشه و اول از همه کانستراکتور همون کلاس فراخوانی میشه
مثال
وقتی 3تا کلاس پدربزگ-کلاس1- و پدر-کلاس2- و فرزند-کلاس 3--رو داریم و کلاس ها رو فراخوانی میکنیم با این دستور که زمانی که کلاسهای پدر و فرزند ساخته شدن سیستم بیاد هردو کلاس رو فراخوانی کنه
و وقتی که یه instance از کلاس فرزند داخل متد mian میسازیم یک -instance –- بصورت اتومات از کلاس پدربزرگ و پدر نیز در حافظه ساخته میشه و حین ایجاد هرکدام از کلاسها سازنده یا کانستراکتور پیش فرض هرکدام در صفحه نشون داده میشن یعنی هرکدام از کلاس ها از کلاس بالایی ارث بری میکنن
سازنده های زنجیره ای constructor chaining
برای شروع سه تا کلاس میسازیم
کلاس حیوان
کلاس انسان
کلاس موجود دریایی بنام 8 پا
سپس میگیم که هرکلاس رو از کلاس بالایی ارث ببره و برای کلاس حیوان کانستراکتور پیشفرض رو میسازیم و هم کانستراکتوری میسازیم که ورودی بگیره اونم از نوع عدد و بهش دستور میدیم که در کانستراکتور تعداد پاهای حیوان را به نمایش بکذاره
و برای کلاس انسان و هشت پا نیز از سازنده پیش فرض استفاده نموده و در ان از کلمه کلیدی base برای اشاره به instance از کلاس بالایی استفاده مینماییم و برای ان ورودی تعیین میکنیم و همان تعداد پاها رو بهش میدیم
و هربار که کلاسی از عناصربالا ساخته بشه و کانستراکتور اولیه فراخوانی میشه و تعداد داده هایی که پیش فرض به کلاس ها دادیم رو برامون چاپ میکنه
در این مثال از کلاس8 پا یه ابجکت ساختیم چون هشت پا فرزند کلاس حیوان هست از کلاس حیوان به کانستراکتور اون اشاره میکنه
و بصورت زنجیره ای به کانستراکتور کلاس حیوان وصل شده و نتیجه هم در شکل زیر مشخصه
namespace Inheritence
{
class Animal
{
public Animal()
{ }
public Animal(int i)
{
Console.WriteLine("Number of legs is:{0}",i);
}
}
class Human:Animal
{
public Human():base(2)
{
}
}
class Octopus : Animal
{
public Octopus() : base(8)
{
}
}
class Program
{
static void Main(string[] args)
{
Octopus cot = new Octopus();
Console.ReadKey();
}
}
}
تصویر اجرا شده مثال
بحث Member Hiding
Member hidingبدین شکل است که ابتدا یک کلاس پدر و فرزند ایجاد میکنیم و کلاس فرزند از کلاس پدر ارث بری میکنه
سپس داخل کلاس پدر متدی تحت عنوان یک ایجاد میکنیم حال اگر این ممبر رو با همین نام در کلاس فرزند ایجاد بکنیم این ممبر در کلاس پدر مخفی خواهد شد یعنی کامپایلر بجای ممبر کلاس پدر ممبر کلاس فرزند رو اجرا خواهد کرد
شکل زیر
در متد main یک ابجکت از کلاس پدر ایجاد میکنیم به متد one میتونیم دسترسی داشته باشیم حتی اگه از کلاس فرزند نیز نمونه بسازیم به همین متد میتونیم دسترسی داشته باشیم چون کلاس فرزند از کلاس پدر ارث بری کرده و متد one در داخل کلاس پدر ایجاد شده است
شکل زیر
حال اگر بنا به نیاز اگه لازم به این باشه که متدی در کلاس پدر داشته باشیم و نیاز به تغییر اون درکلاس فرزند باشه چیکار باید بکنیم
برای اینکار متدی بنام virtualation و override در وراثت خلق شد
یعنی یک ممبر بصورت مجازی در کلاس پدر میتونیم بسازیم و این متد و قابلیت فقط توی کلاس بالایی یعنی پدر میتونه کاربرد داشته باشه
بعد در کلاس فرزند از کلمه کلیدی override استفاده میکنیم به محض درج همین کلمه متدهای مجازی بصورت اتومات در محیط کدنویسی فعال میشن ممبر ما که کلمه ONE بود با انتخاب این کلمه متد جاری در محیط نوشته میشه و در این مرحله ما فقط مجاز به تغییر بدنه تابع هستیم و نمیتونیم عناصر تابع رو تغییر بدیم
در این مرحله اگردر فراخوانی کلاس پدر و فرزند از دو متد همنام استفاده بشه فقط ممبرهای مربوط به هر کلاس اجرا خواهند شد و مانند کدهای قبلی تکرا نخواهد گردید
اما میتونیم از یه قابلیت دیگه اون استفاده کنیم میتوینم متغیری بسازیم که با نوع کلاس پدر باشه ولی رفرنس اون از کلاس فرزند گرفته شده باشه که در این صورت اجرا و فراخوانی کلاس فرزند خواهد بود
static void Main(string[] args)
{
Father cld = new Child();
cld.One();
Console.ReadKey();
}
سی شارپ,مجازی,وراثت,کانستراکت,وراثبت در سی شارپ,inheritance