"> Instantiation اشیا توسط Constructor در سی شارپ

Instantiation اشیا توسط Constructor در سی شارپ

Instantiation اشیا

با توجه به استقبال خوبی که از مقاله ی آموزش Constructor در سی شارپ به عمل آمد تصمیم گرفتیم که این مبحث را با مقاله ای دیگر تکمیل کنیم تا دوستان نیز از اطلاعات آن به طور کامل بهره مند شوند. در این مقاله به سراغ Instantiation شئ در سی شارپ و با استفاده از Constructor میرویم. راه های زیادی برای دستیابی به Instantiation اشیا وجود دارد. در این مقاله ما تعدادی از الگو های مورد استفاده برای نمونه اشیا را با هم بررسی میکنیم …

Instantiation اشیا

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

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

Constructor پیش فرض

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

public class One:Number
{
    public One() { }
}

با استفاده از Constructor ای که تعریف کرده ایم ، یک نمونه از اشیا ایجاد میکنیم :

One objOne = new One();

هربار که ما یک نمونه شئ جدید از کلاس One میسازیم ، متد Constructor اجرا میشود. اگر در قسمت Constructor کدی نیز نوشته شده باشد ، بر روی ایجاد نمونه شئ اجرا میشود.

زمانی که از کلاس زیر نمونه ایجاد میکنیم :

public class Number
{
    protected Number()
    {
        Console.WriteLine(GetType().ToString() + " built");
    }
}

ما یک فراخوان به Constructor و خروجی از کنسول میگیریم.

با استفاده از سی شارپ اگر هیچ Constructor ای مشخص نشده باشد ، به صورت پیش فرض یک Constructor پیش فرض خواهیم داشت. این Constructor پیش فرض هیچ پارامتری نخواهد داشت و هیچ کاری انجام نخواهد داد و همانند آن است که یک Constructor خالی مشخص کرده باشیم ؛ پس اعلام این دو کلاس همانند یکدیگر است :

هیچ Constructor ای تعریف نشود :

public class One:Number{}

Constrcutor پیش فرض تعریف شود :

public class One:Number
{
    public One() { }
}

تغییر Constructor پیش فرض :

همچنین در سی شارپ به محض مشخص کردن یک Constructor با امضایی متفاوت از Constructor پیش فرض ، دیگر Constructor پیش فرض نخواهیم داشت. همانند دو مثال زیر :
تغییر پارامتر ورودی :

Constructor پیش فرض هیچ پارامتری ندارد. پس به محض آنکه یک پارامتر ورودی موردنیاز در آن تعریف کنیم ، Constructor پیش فرض را از دست خواهیم داد :

public class One : Number
{
    public One(int x) { }
}

در این مورد نیاز داریم که یک مقدار عدد صحیح را به نمونه شئ پاس دهیم :

One objOne = new One(3);

تغییر مورد دسترسی :

Constructor پیش فرض به صورت public میباشد ، پس به محض اعلام آنکه Constructor برای کلاس One به صورت private است ، دیگر نمیتوانیم از خارج از کلاس نمونه شئ بسازیم. اکنون شاید برایتان کمی عجیب باشد ، اما در این رابطه در ادامه صحبت خواهیم کرد.

public class One : Number
{
    private One() { }
}

ارائه ی چندین Constructor :

میتوانیم چندین Constructor ارائه کنیم ، پس در این شرایط قابلیت انتخاب اینکه آیا میخواهیم یک مقدار را با Constructor تامین کنیم یا خیر را تنها با نوشتن موارد زیر بدست می آوریم.

public class One : Number
{
    private One() { }
    private One(int x) { }
}

اینکار به اجازه میدهد که نمونه اشیا را با پاس دادن هیچ مقداری یا یک مقدار عدد صحیح در هنگام ایجاد نمونه از کلاس One تعیین کنیم. حال دو معرف زیر قابل قبول است :

One objOne = new One(3);
One objOne = new One();

استفاده از Constructors

تا اینجای کار شاید بگویید که : خب Constructor ها خوب هستند. قبول ! ولی هدف اصلی چیست ؟

هدف اصلی ایجاد Constructor ها ارائه ی هر مقدار دهی اولیه ای است که کلاس احتیاج دارد. بگذارید اینگونه بگویم که ما یک Property داریم که به ما میگوید که چه زمانی شئ نمونه ایجاد شده است. همانند کلاس زیر :

public class Startup
{
    private DateTime m_startDate;
    public DateTime StartDate
    {
        get { return m_startDate; }
    }
}

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

public class Startup
{
    public Startup()
    {
        m_startDate = DateTime.Now;
    }
    private DateTime m_startDate;
    public DateTime StartDate
    {
        get { return m_startDate; }
    }
}

حال ما یک کلاس داریم که در آن به طور یقین مقادیر مقداردهی اولیه میشوند.

فراخوانی Constructor ها در یکدیگر

اگر ما از مثال پیش استفاده کنیم اما بخواهیم قادر باشیم که تاریخ شروع را مشخص کنیم ، میتوانیم Constructor را Overload کنیم :

public class Startup
{
    public Startup()
    {
        m_startDate = DateTime.Now;
    }
    public Startup(DateTime startDate)
    {
        m_startDate = startDate;
    }
    private DateTime m_startDate;
    public DateTime StartDate
    {
        get { return m_startDate; }
    }
}

حال میتوانیم انتخاب کنیم که آیا تاریخ شروع را مشخص کنیم یا خیر. اگر آن را در Constructor مشخص نکنیم ، به صورت پیش فرض تاریخ و زمان جاری را دریافت میکنیم.

این خوب است اما تنها برای اینکه تمرین خوبی داشته باشیم و دانشمان را بیشتر کنیم زمانی که بخواهیم کدمان را نگهداری کنیم ، باید فقط یکی از Constructor ها را به عنوان Master Constructor در نظر بگیریم ؛ جایی که همه ی اتفاق ها می افتد که اگر تغییری در یکی از Constructor ها بوجود آمد ناچار نشویم همه جا را زیر و رو کنیم. Master Constructor آنی است که همه ی مقادیر اعضای داخل کلاس را تنظیم میکند.

public class Startup
{
    // Master constructor:
    // It sets all the values in the class
    public Startup(DateTime startDate)
    {
        m_startDate = startDate;
    }
    private DateTime m_startDate;
    public DateTime StartDate
    {
        get { return m_startDate; }
    }
}

حال کاری که میخواهیم بکنیم این است که همه ی Constructor های دیگر این Master Constructor را صدا بزنند. سینتکس موردنیاز برای زنجیری درآوردن Constructor هایمان به صورت زیر است :

public Startup() : this(DateTime.Now)
    {
    }

پس حالا Constructor پیش فرض ما Master Constructor را فراخوانی خواهد کرد و زمان و تاریخ جاری را به آن پاس میدهد. اگر بخواهیم که تاریخ پیش فرض را در Constructor پیش فرض تغییر دهیم تنها کافیست که مقدار پاس داده شده از طریق Constructor پیش فرض به Master Constructor را به روز رسانی کنیم. این کار در نگاه اول ممکن است خیلی کار بزرگی به نظر نیاید ولی اگر ما تعداد زیادی Constructor از یک شئ داشته باشیم روش خوبی برای سازماندهی کردن آنها خواهد بود و رفتاری سازگار از آنها خواهیم داشت و از تکرار بی مورد کد در جاهای مختلف که ممکن است باعث گم کردن به روز رسانی شود ، جلوگیری میکنیم.

public class Startup
{
    // Master constructor:
    // It sets all the values in the class
    public Startup(DateTime startDate)
    {
        m_startDate = startDate;
    }
    public Startup() : this(DateTime.MinValue) { }
    private DateTime m_startDate;
    public DateTime StartDate
    {
        get { return m_startDate; }
    }
}

فراخوانی Constructor از طریق زنجیره ی وراثت

آخرین چیزی که میخواهیم بررسی کنیم فراخوانمتد های Constructor از طریق زنجیره ی وراثت است.

اگر ما یک کلاس پایه با Constructor های پارامتری داشته باشیم :

public abstract class Animal
{
    public Animal(string name)
    {
        m_name = name;
    }
    private string m_name;
    public string Name
    {
        get { return m_name; }
        set { m_name = value; }
    }
}

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

public class Cat : Animal
{
    public Cat(string name)
        : base(name)
    { }
}

خب . اینها تمام موارد پایه ای مورد نیاز برای Constructor ها و روش اصلی برای Instantiation اشیا بود.

امیدوارم برایتان مفید بوده باشد!
نظرات و پیشنهاداتتان را حتما با من در میان بگذارید.
موفق باشید !

  • پسورد: www.mspsoft.com
مسعود شریفی پور

از سال 88 که با برنامه نویسی آشنا شدم خیلی علاقه مند بودم یک بستر آموزشی بسازم در فضای وب و به انتشار آموزش های در این زمینه بپردازم.حالا یک تیم داریم و با قدرت رو به جلو حرکت میکنیم.

نوشته‌های مرتبط

دیدگاه‌ها

*
*

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