زنگ سی‌شارپ – قسمت سی و هشتم

آشنایی با Inheritance (ارث بری، وراثت)


مسعود درویشیان 9 دیدگاه سی شارپ Friday, 16th August , 2013 26632 بازدید

زنگ سی‌شارپ - قسمت سی و هفتم

Inheritance (وراثت، ارث‌بری)

فهمیدن و درک کردن کلاس‌ها به شما کمک می‌کند تا بتوانید اشیاء را دسته‌بندی و سازماندهی کنید. با دانستن inheritance می‌توانید این دسته‌بندی و سازماندهی را دقیق‌تر انجام دهید. برای مثال، اگر تا به‌حال در مورد Braford چیزی نشنیده باشید، تشکیل تصویر آن در مغزتان کار دشوار و سختی خواهد بود. وقتی می‌دانید که Braford یک حیوان است، تصویر آن می‌تواند راحت‌تر از قبل در ذهن شما مجسم شود. بعد از آن‌که دانستید این حیوان از نوع پستان‌دار است، تصویر آن در ذهن شما بیشتر شکل می‌گیرد و پس از آن‌که دانستید این حیوان یک گاو است، می‌توانید تقریباً به‌طور کامل آن را در ذهنتان مجسم کنید. وقتی‌که پی بردید Braford یک گاو است، ویژگی‌ها و مشخصاتی که در همه‌ی گاوها وجود دارند در ذهن شما مجسم می‌شوند. برای شناسایی یک Braford، تنها کافی است که جزئیات کوچکی مثل رنگ، نشانه‌ها و… را بدانید اما Braford ویژگی و مشخصات کلی خود را به‌ترتیب از حیوانات، پستان‌داران و گاوها به ارث برده است.

هنگامی‌که واژه‌ی ارث‌بری به‌کار می‌رود، ناخودآگاه ذهن‌تان به سمت ارث‌بری ژنتیکی هدایت می‌شود. با استفاده از علم بیولوژی می‌دانید که نوع خون و رنگ چشم شما حاصل ژن‌هایی است که از والدین‌تان به ارث برده‌اید. می‌توان گفت که بسیاری از ویژگی‌ها و رفتارهای شما نیز ارثی هستند. برای مثال، ممکن است لبخندهای شما مانند لبخند مادربزرگتان باشد. همچنین ممکن است دقیقاً همان‌طور که پدرتان راه می‌رود شما نیز، به شکلی مشابه، راه بروید. شما علاوه‌بر این‌که رفتارها و ویژگی‌های خاصی را از والدین خود به ارث می‌برید، ویژگی‌ها و رفتارهای خاص خود را نیز دارید.

Inheritance‌ یکی از اصول بنیادی برنامه‌نویسی شی‌گرا است که موجب ساخت کلاس‌ها به‌صورت سلسله‌مراتبی می‌شود. همه‌ی زبان‌های برنامه‌نویسی شی‌گرا به دلایل یکسانی از inheritance استفاده می‌کنند. با استفاده از inheritance می‌توانید یک کلاس کلی با یک سری ویژگی تعریف کنید که این ویژگی‌ها می‌توانند در تعدادی بخش مرتبط باهم، مشترک باشند. این کلاس کلی، می‌تواند توسط کلاس‌های دیگر، ارث‌بری شود و مواردی که یکتاست را در اختیار آن‌ها قرار دهد. در زبان سی‌شارپ، کلاسی که از آن ارث‌بری می‌شود، base class (کلاس پایه) نام دارد و کلاسی که ارث‌بری را انجام می‌دهد derived class (کلاس مشتق شده) نامیده می‌شود. از این‌رو، derived class نسخه‌ی اختصاصی شده‌ی base class است. derived class تمام variable ها، method ها، property ها و indexer های تعریف شده در base class را به ارث می‌برد و در کنار این‌ها عناصر مخصوص به خود را نیز اضافه می‌کند.

برای آشنا شدن با روند کار inheritance به کلاس زیر توجه کنید:

class Animal
{
    public bool Mammal;
    public string Color;
    public int Weight;
    public string Gender;

    public void Greet()
    {
        Console.WriteLine("The Animal says hello!");
    }
    public void Talk()
    {
        Console.WriteLine("The Animal Talk!");
    }
    public void Eat()
    {
        Console.WriteLine("The Animal Eat!");
    }
}

در کلاس Animal تعدادی متد و متغیر می‌بینید که می‌تواند در همه‌ی حیوانات مشترک باشد. این کلاس را به‌عنوان base class در نظر می‌گیریم. در مرحله‌ی بعد کلاس Dog عناصر این base class را به ارث می‌برد. دقت کنید که کلاس Dog را چگونه تعریف می‌کنیم:

class Dog : Animal
{
    public string DogType { get; set; }
    public string Name { get; set; }

    public void Bark()
    {
        Console.WriteLine(Name + " is barking!");
    }
}

کلاس Dog نوع خاصی از کلاس Animal را می‌سازد. کلاس Dog شامل همه‌ی موارد تعریف شده در کلاس Animal است و علاوه‌بر آن‌ها، دو فیلد و یک متد اضافه‌تر نیز دارد.

به نحوه‌ی استفاده از این کلاس‌ها توجه کنید:

using System;
class Animal
{
    public bool Mammal { get; set; }
    public string Color { get; set; }
    public int Weight { get; set; }
    public string Gender { get; set; }
    public int Age { get; set; }

    public void Greet()
    {
        Console.WriteLine("The Animal says hello!");
    }
    public void Talk()
    {
        Console.WriteLine("The Animal Talk!");
    }
    public void Eat()
    {
        Console.WriteLine("The Animal Eat!");
    }
}
class Dog : Animal
{
    public string Breed { get; set; }
    public string Name { get; set; }

    public void Bark()
    {
        Console.WriteLine(Name + " is barking!");
    }
}
class InheritanceDemo
{
    static void Main()
    {
        Dog dog = new Dog();

        dog.Breed = "Brittany";
        dog.Name = "Ace";
        dog.Gender = "Male";
        dog.Mammal = true;
        dog.Weight = 10;
        dog.Color = "White";
        dog.Age = 1;

        dog.Talk();
        dog.Eat();
        dog.Greet();
        dog.Bark();
    }
}

همان‌طور که می‌بینید، توسط شیء dog میتوانیم به تمام فیلدها و متدهای کلاس Animal دسترسی داشته باشیم. زیرا کلاس Dog از کلاس Animal مشتق شده است.

به syntax ارث‌بری توجه کنید:

class Dog : Animal {

هنگامی‌که یک کلاس از کلاس دیگری ارث‌بری می‌کند، نام base class بعد از نام derived class قرار می‌گیرد که این دو توسط colon از هم جدا شده‌اند.

اگرچه کلاس Animal برای کلاس Dog یک base class است اما این کلاس یک کلاس کاملاً مستقل است. base class بودن برای یک derived class بدین معنا نیست که base class نمی‌تواند به‌صورت مجزا استفاده شود. برای مثال، استفاده از کلاس Animal به شکل زیر هیچ مشکلی ندارد:

Animal animal = new Animal();
animal.Mammal = true;
animal.Talk();

همچنین یک base class هیچ اطلاعاتی در مورد derived class ها ندارد.

به مثال بعدی توجه کنید:

using System;
class TwoDShape
{
    public double Width;
    public double Height;
    public void ShowDim()
    {
        Console.WriteLine("Width and height are " + Width + " and " + Height);
    }
}
class Triangle : TwoDShape
{
    public string Style; 
    public double Area()
    {
        return Width * Height / 2;
    }
    public void ShowStyle()
    {
        Console.WriteLine("Triangle is " + Style);
    }
}
class Shapes
{
    static void Main()
    {
        Triangle t1 = new Triangle();
        Triangle t2 = new Triangle();

        t1.Width = 4.0;
        t1.Height = 4.0;
        t1.Style = "isosceles";

        t2.Width = 8.0;
        t2.Height = 12.0;
        t2.Style = "right";

        Console.WriteLine("Info for t1: ");
        t1.ShowStyle();
        t1.ShowDim();
        Console.WriteLine("Area is " + t1.Area());

        Console.WriteLine();

        Console.WriteLine("Info for t2: ");
        t2.ShowStyle();
        t2.ShowDim();
        Console.WriteLine("Area is " + t2.Area());
    }
}

در این مثال، کلاس TwoDShape شامل فیلدها و متدهای یک شکل دو بعدی است. کلاس Triangle از این base class ارث‌بری کرده و فیلد و متدهای مربوط به خود را به این کلاس افزوده است:

شما تنها می‌توانید یک base class برای هر derived class مشخص کنید. در سی‌شارپ نمی‌توانید چندین base class برای یک derived class داشته باشید زیرا سی‌شارپ از multiple inheritance پشتیبانی نمی‌کند اما می‌توانیدmultiple inheritance را شبیه‌سازی کنید. شما می‌توانید سلسله‌مراتب ارث‌بری را به‌وجود آورید که در آن یک derived class برای کلاس دیگر، base class باشد. توجه کنید که هیچ کلاسی نمی‌تواند (چه به‌طور مستقیم، چه به‌طور غیر مستقیم) base class خودش باشد.

یکی دیگر از مزیت‌های inheritance این است که می‌توانید از یک base class به تعداد دل‌خواه derived class داشته باشد. هر derived class  یک ورژن اختصاصی از base class است. برای مثال، کلاس زیر یک derived class دیگر از کلاس Animal است:

class Cat : Animal
{
    public string Breed { get; set; }
    public void Run()
    {
        Console.WriteLine("The cat is running!");
    }
}

این کلاس نیز مشخصات خود را اضافه کرده است.

اعضای یک کلاس ممکن است بنا به دلایلی، private باشند. هنگامی که از  یک کلاس ارث‌بری می‌کنید، قادر به دیدن اعضای private آن کلاس نخواهید بود. از این‌رو، اگرچه در inheritance می‌توانید به اعضای base class دسترسی داشته باشید، اما به اعضای private آن دسترسی نخواهید داشت. شاید در ابتدا فکر کنید این یک محدودیت جدی است که derived class به اعضای private یک base class دسترسی ندارد اما سی‌شارپ راه‌حل‌هایی برای این مسئله در نظر گرفته است. یکی از این راه‌حل‌ها، اعضای protected هستند که در ادامه به شرح آن‌ها خواهیم پرداخت. یک راه‌حل دیگر استفاده از property های public برای دسترسی و کنترل اطلاعات private است.

به مثال زیر توجه کنید:

using System;
class Human
{
    private int pri_age;
    private int pri_weight;

    public int Age
    {
        get
        {
            return pri_age;
        }
        set
        {
            pri_age = value >= 0 ? value : -value;
        }
    }

    public int Weight
    {
        get
        {
            return pri_weight;
        }
        set
        {
            pri_weight = value >= 0 ? value : -value;
        }
    }
}
class Male : Human
{
    public string Name { get; private set; }
    public int ID { get; private set; }

    public Male(string name, int age, int weight, int id)
    {
        Name = name;
        Age = age;
        Weight = weight;
        ID = id;
    }
}
class InheritDemo
{
    static void Main()
    {
        Male m1 = new Male("John", 26, 70, 180081);

        Console.WriteLine("Name: " + m1.Name);
        Console.WriteLine("Age: " + m1.Age);
        Console.WriteLine("Weight: " + m1.Weight);
        Console.WriteLine("ID: " + m1.ID);

        m1.Age = -30;
        Console.WriteLine(m1.Age); // prints 30

        m1.Weight = -65;
        Console.WriteLine(m1.Weight); // prints 65

        // m1.Name = "Jeremy"; // wrong! Name property is read-only
        // ID = 15567; // wrong! ID property is read-only
    }
}

همان‌طور که می‌بینید، توسط property دسترسی به اعضای private امکان پذیر شده و این دسترسی کنترل شده است. به‌یاد داشته باشید که اعضای private یک کلاس، پیوسته مختص آن کلاس است و هیچ کدی خارج از آن کلاس نمی‌تواند به آن دسترسی داشته باشد، حتی derived classes.

دسترسی به‌صورت Protected (محفوظ)

همان‌طور که گفته شد، اعضای private یک base class برای derived class قابل دسترسی نیست. بنابراین به‌نظر می‌رسد به‌منظور این‌که یکی از اعضای base class در derived class قابل دسترسی باشد، باید آن را به‌صورت public تعریف کنیم و همان‌طور که می‌دانید، اعضای public برای دیگر کدها نیز قابل دسترسی هستند که شاید در این مورد مطلوب نباشد. در این شرایط سی‌شارپ به شما اجازه می‌دهد تا عضوی را به‌صورت protected تعریف کنید. یک عضو protected برای سلسله‌مراتب derived class ها قابل رویت و دسترسی است (public) اما خارج از این سلسله‌مراتب قابل دسترسی نیست  (private).

هنگامی‌که عضوی از کلاس به‌صورت protected تعریف می‌شود، آن عضو در واقع با یک استثنا، private است و این استثنا زمانی است که از آن عضو protected، ارث‌بری می‌شود. در این مورد، یک عضو protected در base class تبدیل به یک عضو protected در یک derived class می‌شود و این روند همین‌طور ادامه خواهد یافت. بنابراین اعضای protected فقط در سلسله‌مراتب ارث‌بری قابل دسترسی بوده و خارج از این سلسله‌مراتب، private هستند. از این‌رو، با استفاده از protected می‌توانید اعضایی تعریف کنید که private هستند اما می‌توان از آن‌ها در ارث‌بری استفاده کرد.

به مثال زیر توجه کنید:

using System;
class A
{
    protected int i, j;

    public void Set(int a, int b)
    {
        i = a;
        j = b;
    }

    public void Show()
    {
        Console.WriteLine(i + " " + j);
    }
}
class B : A
{
    private int k;

    public void SetK()
    {
        // B can access A's i and j
        k = i * j;
    }

    public void ShowK()
    {
        Console.WriteLine(k);
    }
}
class ProtectedDemo
{
    static void Main()
    {
        B ob = new B();

        ob.Set(2, 3);
        ob.Show();

        ob.SetK();
        ob.ShowK();
    }
}


نویسنده / مترجم : مسعود درویشیان

علاقه مند به موسیقی و برنامه نویسی بازی


9 دیدگاه برای این نوشته ثبت شده است

  1. کارتون درسته
    با تشکر




  2. حسین
    21 August 2013

    سلام خیلی ممنون….خسته نباشید….من تازه آموزش های سی شارپتونو دیدم میخوام برم از اولیش شروع کنم..به نظرم عالی باشه….فقط تورو خدا مثل بعضی از آموزش ها که نصفه میزارن میمونه شما هم ول نکنین وسطش یهو…بعد دو تا سوال هم داشتم!
    1- به نظرتون کل آموزش ها چند تا میشه؟؟؟ یعنی چند درس میشه؟
    2-اینکه سی شارپ دات نت برای کار توی وب فرقی با سی شارپی که شما آموزش میدین نداره که؟فقط محیط کارشون فرق داره؟
    خیلی ممنون.




  3. عبدالغفور صبوری
    7 September 2013

    میشه در قسمت سی شارپ آموزش کابردی ADO.Net رو هم بذارید چون واقعا نیاز داریم. اگه میشه ممنون.




  4. سمیه
    7 January 2014

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




  5. هادی
    5 March 2014

    salam vaghean mamnoon. aliye.




  6. سایت عکس
    31 May 2014

    آموزش مفیدی بود ممنون




  7. مهدی
    9 August 2014

    دمتون گرم




  8. علی
    15 May 2015

    your site is my favorite space to come!



دیدگاه خود را بنویسید





نشانی ایمیل شما منتشر نخواهد شد.

کامنت های شما بعد از تأیید توسط نویسنده وبلاگ، منتشر خواهند شد.

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

شما میتوانید با مراجعه به سایت گراواتار یک آواتار اختصاصی برای خود تعریف کنید، تا در کنار نام شما نمایش داده شود

برای قرار دادن کدهای نمونه می توانید از تگ های [php] ، [html] ، [css] و [js] استفاده کنید.
به عنوان مثال کدهای php را می توان به صورت زیر قرار داد:
[php] var $whoLoveIranians = "WebTarget!"; [/php]



کلیه حقوق مادی و معنوی برای وب سایت وب تارگت محفوظ است ©2024 وب‌تارگت

استفاده از مطالب وب سایت در سایر وب سایت‌ها و نشریات چاپی با ذکر منبع آزاد است.