TAHA
09-29-2009, 07:16 AM
کلاس ها در سی شارپ :
تا بحال در حد کاربرد ، با کلاس ها آشنا شده ایم . اما در این قسمت می خواهیم نگاهی دقیق تر به کلاس ها بیاندازیم.
هر کدی در سی شارپ قسمتی از یک کلاس می باشد و ترکیب تمام خواص و متدهای موجود در یک کلاس یک نوع داده ی جدید تعریف شده از طرف ما را پدید می آورد. هر متغیری که از کلاس ساخته شود ، شیء نامیده می شود و یک کپی منحصر به فرد است. برای مثال برنامه ی زیر را درنظر بگیرید :
using System;
class Data
{
public int x;
}
class App
{
public static void Main()
{
Data d1 = new Data();
d1.x = 1;
Data d2 = new Data();
d2.x = 2;
Console.WriteLine("d1.x = {0}", d1.x);
Console.WriteLine("d2.x = {0}", d2.x);
}
}در اینجا کلاس Data تعریف شده است و دارای یک عضو به نام x می باشد. به این نوع داده در کلاس فیلد گفته می شود و هنگامیکه به صورت public معرفی می شود یعنی خارج از کلاس نیز قابل دسترسی است. در کد بالا دو متغیر از کلاس تعریف و مقدار دهی اولیه شده اند. خروجی برنامه به صورت زیر است :
d1.x = 1
d2.x = 2دلیل این خروجی آن است که هر instance (نمونه) از کلاس منحصر بفرد است و در اینجا نمی توان انتظار داشت که هر دو خروجی یکی شوند.
برای مقدار دهی اولیه متغیرهایی که به صورت فیلد تعریف می شوند ، بهتر است مقدار دهی آنها را در سازنده ی کلاس (constructor) انجام دهیم.
class Data
{
public int x;
public Data(){x = 99;}
}همانطور که پیشتر نیز ذکر شد ، متدی که هم نام کلاس است ، سازنده نام می گیرد. یک کلاس می تواند بیش از یک سازنده داشته باشد. برای مثال :
کد:
class Data
{
public int x;
private Data(){}
public Data(int y){x = y;}
public Data(int y, int z){x = y + z;}
}از آنجائیکه که سازنده ی بدون پارامتر ذکر شده در کد فوق private تعریف شده است بنابراین خارج از کلاس دیگر قابل دسترسی نمی باشد . بنابراین کدی خارج از کلاس ، تنها می تواند از دو سازنده ی دیگر استفاده کند. برای مثال تعریف دو متغیر جدید از این کلاس به صورت زیر می باشد :
Data d1 = new Data(44);
Data d2 = new Data(22, 33);سی شارپ به شما اجازه می دهد تا سازنده ها را در یک کلاس توسط کلمه ی کلیدی this نیز فراخوانی کنید یعنی بجای ذکر نام متد سازنده از کلمه ی this استفاده شود ( در خود کلاس ) .
اگر می خواهید متغیری را بین نمونه (instance) های مختلف یک کلاس به اشتراک بگذارید کلمه ی کلیدی static وارد صحنه می شود. به مثال زیر توجه کنید :
using System;
class Counted
{
public static int count = 0;
public Counted()
{
count++;
}
public int GetInstanceCount()
{
return count;
}
}
class App
{
public static void Main()
{
Counted d1 = new Counted();
Console.WriteLine("current total {0}", d1.GetInstanceCount());
Counted d2 = new Counted();
Console.WriteLine("current total {0}", d2.GetInstanceCount());
Console.WriteLine("total {0}", Counted.count);
}
}باید خاطر نشان کرد که متغیرهای استاتیک توسط نمونه های کلاس قابل دستیابی نیستند و فقط درون کلاس به شکل زیر می توان از آْنها استفاده کرد :
کد:
<classname>.<staticmembername>در مثال فوق دو نمونه از کلاس Counted تعریف شده است. با هر بار فراخوانی کلاس ، خودبخود سازنده اجرا شده و یک عدد به این شمارشگر استاتیک اضافه می شود. همانطور که ذکر شد، برای اینکه بتوان به این متغیر استاتیک در خارج از کد دسترسی پیدا کرد یک متد غیر استاتیک تعریف شده است.
در مثال فوق تابع GetInstanceCount تنها یک عدد را بر می گرداند. در برنامه نویسی شیء گرا مرسوم است که در این حالت به جای توابع از خواص استفاده شود که به اندازه ی کافی در مورد آنها در قسمت های قبل توضیح داده شد. در این صورت تعریف فوق به صورت زیر در می آید :
class Counted
{
public static int x = 0;
public Counted()
{
x++;
}
public int InstanceCount // property
{
get{return x;}
}
}و در این صورت قسمت بعدی کد به صورت زیر اصلاح می شود (فراخوانی خواص ، بدون ذکر پرانتزها بعد از نام آنها صورت می گیرد):
Counted d1 = new Counted();
Console.WriteLine("current total {0}", d1.InstanceCount);
Counted d2 = new Counted();
Console.WriteLine("current total {0}", d2.InstanceCount);اگر یک خاصیت هم خواندنی و هم نوشتنی باشد به صورت زیر تعریف می شود :
private string name;
public string Name
{
get{return name;}
set{name = value;}
}فیلدهای پابلیک را می توان خواند و یا تغییر داد. اگر لازم باشد تا کاربر نتواند آنها را تغییر دهد می توان از کلمه ی کلیدی readonly قبل از تعریف آنها استفاده کرد. مثال :
class Data
{
public readonly int x = 42;
}بحث کلاس ها ادامه دارد...
تا بحال در حد کاربرد ، با کلاس ها آشنا شده ایم . اما در این قسمت می خواهیم نگاهی دقیق تر به کلاس ها بیاندازیم.
هر کدی در سی شارپ قسمتی از یک کلاس می باشد و ترکیب تمام خواص و متدهای موجود در یک کلاس یک نوع داده ی جدید تعریف شده از طرف ما را پدید می آورد. هر متغیری که از کلاس ساخته شود ، شیء نامیده می شود و یک کپی منحصر به فرد است. برای مثال برنامه ی زیر را درنظر بگیرید :
using System;
class Data
{
public int x;
}
class App
{
public static void Main()
{
Data d1 = new Data();
d1.x = 1;
Data d2 = new Data();
d2.x = 2;
Console.WriteLine("d1.x = {0}", d1.x);
Console.WriteLine("d2.x = {0}", d2.x);
}
}در اینجا کلاس Data تعریف شده است و دارای یک عضو به نام x می باشد. به این نوع داده در کلاس فیلد گفته می شود و هنگامیکه به صورت public معرفی می شود یعنی خارج از کلاس نیز قابل دسترسی است. در کد بالا دو متغیر از کلاس تعریف و مقدار دهی اولیه شده اند. خروجی برنامه به صورت زیر است :
d1.x = 1
d2.x = 2دلیل این خروجی آن است که هر instance (نمونه) از کلاس منحصر بفرد است و در اینجا نمی توان انتظار داشت که هر دو خروجی یکی شوند.
برای مقدار دهی اولیه متغیرهایی که به صورت فیلد تعریف می شوند ، بهتر است مقدار دهی آنها را در سازنده ی کلاس (constructor) انجام دهیم.
class Data
{
public int x;
public Data(){x = 99;}
}همانطور که پیشتر نیز ذکر شد ، متدی که هم نام کلاس است ، سازنده نام می گیرد. یک کلاس می تواند بیش از یک سازنده داشته باشد. برای مثال :
کد:
class Data
{
public int x;
private Data(){}
public Data(int y){x = y;}
public Data(int y, int z){x = y + z;}
}از آنجائیکه که سازنده ی بدون پارامتر ذکر شده در کد فوق private تعریف شده است بنابراین خارج از کلاس دیگر قابل دسترسی نمی باشد . بنابراین کدی خارج از کلاس ، تنها می تواند از دو سازنده ی دیگر استفاده کند. برای مثال تعریف دو متغیر جدید از این کلاس به صورت زیر می باشد :
Data d1 = new Data(44);
Data d2 = new Data(22, 33);سی شارپ به شما اجازه می دهد تا سازنده ها را در یک کلاس توسط کلمه ی کلیدی this نیز فراخوانی کنید یعنی بجای ذکر نام متد سازنده از کلمه ی this استفاده شود ( در خود کلاس ) .
اگر می خواهید متغیری را بین نمونه (instance) های مختلف یک کلاس به اشتراک بگذارید کلمه ی کلیدی static وارد صحنه می شود. به مثال زیر توجه کنید :
using System;
class Counted
{
public static int count = 0;
public Counted()
{
count++;
}
public int GetInstanceCount()
{
return count;
}
}
class App
{
public static void Main()
{
Counted d1 = new Counted();
Console.WriteLine("current total {0}", d1.GetInstanceCount());
Counted d2 = new Counted();
Console.WriteLine("current total {0}", d2.GetInstanceCount());
Console.WriteLine("total {0}", Counted.count);
}
}باید خاطر نشان کرد که متغیرهای استاتیک توسط نمونه های کلاس قابل دستیابی نیستند و فقط درون کلاس به شکل زیر می توان از آْنها استفاده کرد :
کد:
<classname>.<staticmembername>در مثال فوق دو نمونه از کلاس Counted تعریف شده است. با هر بار فراخوانی کلاس ، خودبخود سازنده اجرا شده و یک عدد به این شمارشگر استاتیک اضافه می شود. همانطور که ذکر شد، برای اینکه بتوان به این متغیر استاتیک در خارج از کد دسترسی پیدا کرد یک متد غیر استاتیک تعریف شده است.
در مثال فوق تابع GetInstanceCount تنها یک عدد را بر می گرداند. در برنامه نویسی شیء گرا مرسوم است که در این حالت به جای توابع از خواص استفاده شود که به اندازه ی کافی در مورد آنها در قسمت های قبل توضیح داده شد. در این صورت تعریف فوق به صورت زیر در می آید :
class Counted
{
public static int x = 0;
public Counted()
{
x++;
}
public int InstanceCount // property
{
get{return x;}
}
}و در این صورت قسمت بعدی کد به صورت زیر اصلاح می شود (فراخوانی خواص ، بدون ذکر پرانتزها بعد از نام آنها صورت می گیرد):
Counted d1 = new Counted();
Console.WriteLine("current total {0}", d1.InstanceCount);
Counted d2 = new Counted();
Console.WriteLine("current total {0}", d2.InstanceCount);اگر یک خاصیت هم خواندنی و هم نوشتنی باشد به صورت زیر تعریف می شود :
private string name;
public string Name
{
get{return name;}
set{name = value;}
}فیلدهای پابلیک را می توان خواند و یا تغییر داد. اگر لازم باشد تا کاربر نتواند آنها را تغییر دهد می توان از کلمه ی کلیدی readonly قبل از تعریف آنها استفاده کرد. مثال :
class Data
{
public readonly int x = 42;
}بحث کلاس ها ادامه دارد...