منو

کلاس های abstract و sealed(قسمت بیست و دوم)

کلاس های abstract و sealed
لیست جلسات
DatoosTech img Course

قسمت پنجم

دستورات کنسول و متغیرها

DatoosTech img Course

قسمت ششم

نوع های داده اولیه

DatoosTech img Course

قسمت هفتم

عملگرهای زبان سی شارپ

DatoosTech img Course

قسمت هشتم

دستورات کنترلی if else

DatoosTech img Course

قسمت نهم

دستورات کنترلی switch

DatoosTech img Course

قسمت دهم

حلقه for

DatoosTech img Course

قسمت دوازدهم

حلقه while

DatoosTech img Course

قسمت دوازدهم

آرایه ها و دستور foreach

DatoosTech img Course

قسمت سیزدهم

متدها در زبان سی شارپ (بخش اول)

DatoosTech img Course

قسمت چهاردهم

متدها در زبان سی شارپ (بخش دوم)

DatoosTech img Course

قسمت پانزدهم

مقدمه برنامه نویسی شی گرا

DatoosTech img Course

قسمت شانزدهم

کلاس، اشیاء و فضاهای نام

DatoosTech img Course

قسمت هفدهم

فیلدها و رفتارها

DatoosTech img Course

قسمت هجدهم

Property ها

DatoosTech img Course

قسمت نوزدهم

سازنده ها و روش های ایجاد اشیاء

DatoosTech img Course

قسمت بیستم

وراثت یا Inheritance

DatoosTech img Course

قسمت بیست و یکم

آشنایی با مفهوم Polymorphism

DatoosTech img Course

قسمت بیست و دوم

کلاس های abstract و sealed

DatoosTech img Course

قسمت بیست و سوم

سازنده ها در وراثت، کلمه کلیدی protected و فیلدهای readonly

DatoosTech img Course

قسمت بیست و چهارم

کلاس های static و partial و Extension Method ها

DatoosTech img Course

قسمت بیست و پنجم

Reference Types و Value Types

DatoosTech img Course

قسمت بیست و ششم

آشنایی با کاربرد interface ها

DatoosTech img Course

قسمت بیست و هفتم

مفاهیم Inversion of Control و Dependency Injection

DatoosTech img Course

قسمت بیست و هشتم

Type Casting و انواع Cast ها

DatoosTech img Course

قسمت بیست و نهم

operator overloading و تعریف cast ها

DatoosTech img Course

قسمت سی ام

مفاهیم boxing و unboxing

DatoosTech img Course

قسمت سی و یکم

قابلیت Generics

DatoosTech img Course

قسمت سی و دوم

نکات تکمیلی Generic ها، کلاس List و کلاس Dictionary

DatoosTech img Course

قسمت سی و سوم

استثناء ها (Exceptions) و مدیریت خطاها

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

کلاس ها و اعضاء abstract


به بخش قبل و کلاس Shape بر میگردیم که سه کلاس فرزند از روی آن ها ساخته بودیم:

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

public class Rectangle : Shape
{
         
}
 
public class Triangle : Shape
{
         
}
 
public class Circle : Shape
{
         
}
            
        

کلاس Shape به تنهایی برای ما کاربردی نداشته و تنها داخل کد باید از کلاس های فرزند استفاده کرد، یعنی نباید از روی کلاس Shape شئ ایجاد شود. برای اینکار کافیست کلاس Shape را از نوع abstract تعریف کنیم:

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

حال اگر بخواهیم از روی کلاس Shape یک شئ ایجاد کنیم با پیغام خطا مواجه خواهیم شد:

abstract1


اما کاربرد کلاس های abstract به همین جا ختم نمی شود، در قسمت قبل متد Draw را در کلاس Shape به صورت virtual تعریف کرده و در کلاس های فرزند آن را override کردیم. یکی از قابلیت های زبان سی شارپ، تعریف متدها به صورت abstract می باشد. متدهای abstract تنها شامل signature که در قسمت های اولیه با آن آشنا شدیم می باشد و بدنه ندارد، علاوه بر آن تمامی کلاس هایی که از یک کلاس abstract مشتق می شوند، در صورتی که کلاس abstract رفتار یا خاصیتی از نوع abstract داشته باشد، باید حتماً آن رفتار یا خاصیت را override کنند. برای مثال کلاس Shape را به صورت زیر تغییر می دهیم:

 
        
public abstract class Shape
{
    public abstract void Draw();
}
            
        

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

abstract2


می توانیم به صورت دستی متد Draw را تعریف کرده یا از قابلیت Resharper برای پیاده سازی اعضای abstract به صورت خودکار استفاده کنیم. برای انکار مکان نما را بر روی نام کلاس قرار داده و کلید های Alt+Enter را فشار می دهیم. با این کار منویی با نام Action Context نمایش داده می شود:

abstract3


از منوی ظاهر شده، گزینه Implement missing members را انتخاب می کنیم تا اعضای abstract پیاده سازی شوند. بعد از اینکار کد کلاس Rectangle به صورت زیر خواهد بود:

 
        
public class Rectangle : Shape
{
    public override void Draw()
    {
        throw new NotImplementedException();
    }
}
            
        

کدی که به صورت خودکار داخل بدنه متد Draw قرار گرفته مربوط به یکی از ویژگی های زبان سی شارپ با نام استثناها یا Exceptions می باشد که در بخش های بعدی با آن آشنا می شویم. حال کد مورد نظر را داخل متد Draw می نویسیم:

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

در صورتی که Resharper را نصب ندارید، برای پیاده سازی خودکار اعضاء abstract کلاس می توانید از قابلیت خود Visual Studio استفاده کنید. برای اینکار، مکان نما را به انتهای اول تعریف کلاس برده و کلید های Alt+. را فشار دهید. منویی به صورت زیر نمایش داده می شود:

abstract4


با انتخاب گزینه Implement abstract class Shape اعضاء ای که از نوع abstract تعریف شده اند در کلاس پیاده سازی می شوند.

این قابلیت دقیقاً کار مشابهی با متدهای virtual انجام می دهد، با این تفاوت که متدهای abstract بدنه ای ندارند، اما اعضاء virtual می توانند بدنه ای داشته باشند که بوسیله کلمه کلیدی base می توان به آنها در کلاس فرزند دسترسی داشت. همچنین توجه کنید که اعضاء abstract تنها داخل کلاس های abstract قابل تعریف هستند.


کلاس ها و اعضاء sealed


در قسمت وراثت گفتیم که می توان زنجیره وراثت داشت. یعنی کلاس B از کلاس A و کلاس C از کلاس B مشتق شوند. اما فرض کنید بخواهیم زنجیره وراثت را در یک کلاس قطع کنیم. یعنی کلاس دیگری نتواند از کلاس ما ارث بری کند. برای اینکار کافیست کلاس مورد نظر را از نوع sealed تعریف کرد:

 
        
public class A
{
        
}

public sealed class B : A
{
        
}
            
        

در کد بالا کلاس B از نوع sealed تعریف شده، بدین معنا که هیچ کلاس دیگری نمی تواند از این کلاس مشتق شود. در تصویر زیر، کلاس C از کلاس B مشتق شده و پیغام خطا دریافت کردیم:

sealed1


یکی دیگر از کاربردهای کلمه کلیدی sealed جلوگیری از override کردن یک متد است. کلاس Shape و Rectangle را مثال میزنیم. میخواهیم اگر کلاسی از کلاس Rectangle مشتق شد قابلیت ovverride ردن متد Draw را نداشته باشد. کافیست متد Draw را از نوع sealed تعریف کنیم:

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

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

همانطور که در کد بالا مشاهده می کنید، متد Draw در کلاس Rectangle از نوع sealed تعریف شده. حالا اگر کلاسی تعریف کنیم و آن را کلاس Rectangle مشتق کنیم، در کلاس فرزند قابلیت تعریف مجدد متد Draw را نخواهیم داشت.

تا این قسمت از آموزش با کلیات برنامه نویسی شئ گرا، مفاهیم وراثت و Polymorphism و همچنین کلاس های abstract و sealed آشنا شدیم. در بخش های بعدی با تکمیلی برنامه نویسی شئ گرا آَشنا شده و مباحث Casting را با هم بررسی خواهیم کرد.