در توسینسو تدریس کنید

و

با دانش خود درآمد کسب کنید

آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 7 : Polymorphism

همانطور که در بخش قبل گفتیم وراثت یکی از اصلی ترین مباحث برنامه نویسی شئ گرا می باشد. در بخش قبلی با شیوه ارث بری از کلاس ها آشنا شدیم. یکی از مفاهیمی که در برنامه نویسی شئ گرا خیلی کاربرد دارد و وابسته به مفهوم وراثت است، چند ریختی یا Polymorphism است. در قسمت مقدمه برنامه نویسی شئ گرا با تعریف کلی Polymorphism آشنا شدیم و در این بخش تصمیم داریم به صورت عملی با نحوه پیاده سازی این قابلیت در زبان سی شارپ آشنا شویم.همانطور که در قسمت مقدمه گفتیم، Polymorphism به معنای قابلیت تعریف مجدد رفتار یک موجودیت در کلاس های فرزند می باشد. Polymorphism در زبان سی شارپ به سه روش قابل پیاده سازی است:

  1. استفاده از متد های virtual و override کردن آنها در کلاس های فرزند
  2. استفاده از رفتارهای abstract در کلاس والد
  3. استفاده از قابلیت interface ها

در این قسمت، حالت اول را بررسی می کنیم و حالت دوم و سوم، یعنی استفاده از متدهای abstract و interface ها را در بخش های بعدی توضیح خواهیم داد.

متدهای virtual

همانطور که گفتیم یکی از روش های پیاده سازی Polymorphism استفاده از متدهای virtual و override کردن آنها در کلاس فرزند است. برای مثال، فرض کنیم کلاس پایه ای داریم با عنوان Shape که در آن رفتاری با نام Draw تعریف کردیم. رفتار Draw وظیفه ترسیم شئ را بر عهده دارد. در این مثال ها، تنها در متدها پیامی را در پنجره کنسول چاپ می کنیم، اما در محیط واقعی هر یک از این متدها وظیفه ترسیم شئ را بر عهده خواهند داشت. همانطور که گفتیم کلاس Shape رفتار Draw را تعریف می کند. این رفتار در بین تمامی اشیاء ای که از کلاس Shape مشتق می شوند مشترک است. در ابتدا کلاس Shape را به صورت زیر تعریف می کنیم:

public class Shape
{
    public void Draw()
    {
        Console.WriteLine("Drawing the shape!");
    }
}

حالا باید کلاس های فرزند را تعریف کنیم. ما سه کلاس به نام های Rectangle، Triangle و Circle که وظیفه ترسیم مستطیل، مثلث و دایره را بر عهده دارند تعریف می کنیم که هر سه از کلاس Shape مشتق شده اند:

public class Rectangle : Shape
{
        
}

public class Triangle : Shape
{
        
}

public class Circle : Shape
{
        
}

هر سه کلاسی که در بالا تعریف کردیم، شامل متد Draw هستند، زیرا این متد در کلاس پایه یعنی Shape تعریف شده است. حال از هر یک، شئ ای ساخته و متد Draw را صدا می زنیم:

var rect = new Rectangle();
var tri = new Triangle();
var circ = new Circle();

rect.Draw();
tri.Draw();
circ.Draw();

Console.ReadKey();

خروجی دستورات بالا به صورت زیر می باشد:

Drawing the shape!
Drawing the shape!
Drawing the shape!

اما خروجی مدنظر ما تولید نشده است. ما می خواهیم هر کلاس رفتار مربوط به خود را داشته باشد. درست است که رفتار Draw در کلاس پایه تعریف شده، اما باید بتوانیم این رفتار را برای کلاس های فرزند تغییر دهیم. برای اینکار باید در کلاس پایه مشخص کنیم که کدم رفتار را می خواهیم تغییر دهیم. برای اینکار، کافیست رفتار مورد نظر را از نوع virtual تعریف کنیم. اعضای virtual به ما این اجازه را می دهند تا در کلاس فرزند مجدد آنها را تعریف کنیم. برای اینکار متد Draw در کلاس Shape را به صورت زیر تغییر می دهیم:

public virtual void Draw()
{
    Console.WriteLine("Drawing the shape!");
}

دقت کنید، کلمه کلیدی virtual قبل از نوع بازگشتی متد نوشته می شود. حالا باید در کلاس فرزند رفتار Draw را مجدداً تعریف کنیم. برای اینکار باید متدی که از نوع virtual تعریف شده است را override کنیم. ابتدا رفتار Draw را برای کلاس Rectangle تغییر می دهیم. کد کلاس Rectangle را به صورت زیر تغییر دهید:

public class Rectangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Drawing rectangle!");
    }
}

حالا با اجرای مجدد کد خروجی به صورت زیر تغییر می کند:

Drawing rectangle!
Drawing the shape!
Drawing the shape!

زمانی که شما داخل کلاس Rectangle شروع به تایپ می کنید، بعد از نوشتن کلمه کلیدی override و زدن کلید space لیستی از متدهایی که قابل override شدن هستند برای شما نمایش داده می شوند:

img1

همچنین در صورتی که ابزار Resharper را نصب کرده باشید، وارد scope کلاس شده و کلید های Alt+Insert را فشار دهید، با اینکار منوی Generate برای شما نمایش داده می شود، از طریق این منو و انتخاب گزینه Overriding members لیستی از تمامی اعضای قابل override شدن به شما نمایش داده می شود:

img2

img3

بعد از انتخاب عضو مورد نظر و فشار دادن کلید Finish متد مورد نظر برای شما override می شود. مهمترین کاربرد این ویژگی، زمانی است که شما تصمیم دارید چندین ویژگی را با هم override کنید. به یک نکته توجه داشته باشید، چه با روش اول متد را override کنید، چه با روش دوم، کدی برای شما به صورت خودکار درج می شود که به صورت زیر است:

public override void Draw()
{
    base.Draw();
}

در قسمت قبل با کلمه کلیدی base آشنا شدید، در کد بالا که به صورت پیش فرض نوشته می شود، با فراخوانی متد Draw از شئ ای که متد داخل آن override شده، نسخه کلاس پایه از رفتار فراخوانی می شود که شما باید بر اساس نیاز خود کد مورد نظر را برای رفتار override شده بنویسید.کلاس های Triangle و Circle را نیز به صورت زیر تغییر می دهیم:

public class Triangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Draw triangle!");
    }        
}

public class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Draw circle!");
    }        
}

بعد از اجرای برنامه، خروجی باید به صورت زیر باشد:

Drawing rectangle!
Drawing triangle!
Drawing circle!

شاید خیلی از دوستان این سوال برایشان پیش بیاید که دلیل اینکار چیست؟ ما که متدها را در هر کلاس نوشتیم، چرا باید از کلاس پایه و override کردن آنها استفاده می کردیم؟ مهمترین خاصیت استفاده از Polymorphism استفاده از کلاس پدر برای کارهاست. برای درک بهتر، فرض کنید میخواهیم آرایه ای از اشیاء داشته باشیم. همانطور که می دانید، ما سه کلاس مختلف داریم و در صورت استفاده نکردن از قابلیت وراثت باید برای هر یک از کلاس ها یک آرایه تعریف کنیم. اما با قابلیت وراثت می توان یک آرایه از نوع کلاس پایه تعریف کرد و اشیاء فرزند را داخل آن قرار داد:

Shape[] shapes = new Shape[5];
shapes[0] = new Circle();
shapes[1] = new Triangle();
shapes[2] = new Circle();
shapes[3] = new Rectangle();
shapes[4] = new Triangle();

foreach (var shape in shapes)
    shape.Draw();

Console.ReadKey();

با اجرای کد بالا خروجی زیر به نمایش داده می شود:

Drawing circle!
Drawing triangle!
Drawing circle!
Drawing rectangle!
Drawing triangle!

با اینکه ما کلاس پایه یعنی Shape را به عنوان نوع آرایه در نظر گرفتیم، اما در هر خانه از آرایه ای شئ ای از نوع فرزندان کلاس Shape قرار دادیم و به دلیل override کردن رفتار Draw در کلاس های مشتق شده، فراخوانی متد Draw بر اساس تعریفی که در کلاس های فرزند داشتیم انجام می شود.تعریف مجدد یا override کردن تنها محدود به رفتارها یا همان متدها نمی باشد. شما خصوصیات یا Property ها را نیز می توانید از نوع virtual تعریف کنید. برای مثال کلاسی را با نام Human فرض کنید که دارای سه خصوصیت به نام های FirstName و LastName و FullSpecification می باشد:

public class Human
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public string FullSpecification
    {
        get { return FirstName + " " + LastName; }
    }
}

در کلاس بالا، خاصیت FullSpecification نام کامل را بر میگرداند. حالا کلاس فرزندی تعریف می کنیم با نام Employee یا کارمند که از کلاس Human مشتق شده است و خاصیت جدید با نام JobPosition یا موقعیت شغلی به آن اضافه می کنیم:

public class Employee : Human
{
    public string JobPosition { get; set; }
}

در صورتی که شئ ای از روی Employee بسازیم و خاصیت FullSpecification آن را چاپ کنیم، نام و نام خانوداگی او در خروجی چاپ می شود. اما می خواهیم این خاصیت علاوه بر نام کامل، موقعیت شغلی او را نیز در خروجی چاپ کند. برای اینکار کافیست که در کلاس Human خاصیت FullSpecification را به صورت virtual تعریف کرده و در کلاس فرزند مجدد بخش get آن را تعریف کنیم:

public class Human
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual string FullSpecification
    {
        get { return FirstName + " " + LastName; }
    }
}

public class Employee : Human
{
    public string JobPosition { get; set; }

    public override string FullSpecification
    {
        get { return base.FullSpecification + " with job position: " + JobPosition; }
    }
}

در کلاس Employee به بخش get توجه کنید:

get { return base.FullSpecification + " with job position: " + JobPosition; }

در این قسمت، از کلمه کلیدی base برای گرفتن مقدار FullSpecification استفاده شده است. این خاصیت نام کامل را برای ما بر میگرداند و ما به انتهای آن موقعیت شغلی شخص را اضافه می کنیم و بر میگردانیم.قابلیت Polymorphism در برنامه نویسی شئ گرا نقش بسیار پر رنگی دارد و خیلی جاها از نوشتن کدهای تکراری جلوگیری کرده و حجم کد برنامه شما را به صورت محسوسی کاهش می دهد. در بخش بعدی آموزش زبان سی شارپ، با کلاس ها و متدهای abstract و همچنین کلاس های sealed آشنا می شویم. ITPRO باشید

نویسنده : حسین احمدی

منبع : جزیره برنامه نویسی وب سایت توسینسو

هرگونه نشر و کپی برداری بدون ذکر منبع و نام نویسنده دارای اشکال اخلاقی است

#override_کردن_متدها_در_سی_شارپ #آموزش_زبان_سی_شارپ #برنامه_نویسی_شئ_گرا #متدهای_virtual_در_سی_شارپ #polymorphism_در_شئ_گرایی #polymorphism_در_برنامه_نویسی_شئ_گرا #آموزش_برنامه_نویسی_شئ_گرا #وراثت_در_برنامه_نویسی_شئ_گرا #آشنایی_با_مفهوم_polymorphism #آموزش_برنامه_نویسی
عنوان
1 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 1 : مقدمه رایگان
2 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 2 : کلاس، اشیاء رایگان
3 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 3 : فیلد و رفتار رایگان
4 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 4 : Property ها رایگان
5 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 5 : ایجاد اشیاء رایگان
6 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 6 : وراثت رایگان
7 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 7 : Polymorphism رایگان
8 آموزش برنامه نویسی شی گرا در (#C) قسمت 8 : abstract و sealed رایگان
9 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 9:سازنده در وراثت رایگان
10 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 10 : متد Extension رایگان
11 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 11: Value ها رایگان
12 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 12 : Interface رایگان
13 آموزش برنامه نویسی شی گرا در (#C) قسمت 13: Dependency Injection رایگان
14 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 14 : انواع Cast ها رایگان
15 آموزش برنامه نویسی شی گرا (#C) قسمت 15 : Operator Overloading رایگان
16 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 16 : Box و Unbox رایگان
17 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 17 : Generics رایگان
18 آموزش برنامه نویسی شی گرا در (#C) قسمت 18 : List و Dictionary رایگان
19 آموزش برنامه نویسی شی گرا در سی شارپ (#C) قسمت 19 : مدیریت خطاها رایگان
زمان و قیمت کل 0″ 0
3 نظر
سلمان بدرقه

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

حسین احمدی

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

جلال مقدم

عرض ادب و خسته نباشید.

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

نظر شما
برای ارسال نظر باید وارد شوید.
از سرتاسر توسینسو
تنظیمات حریم خصوصی
تائید صرفنظر
×

تو می تونی بهترین نتیجه رو تضمینی با بهترین های ایران بدست بیاری ، پس مقایسه کن و بعد خرید کن : فقط توی جشنواره تابستانه می تونی امروز ارزونتر از فردا خرید کنی ....