آموزش سی شارپ - قسمت چهارم
Person p = new Person();
همانطور كه قبلا هم گفتم براي استفاده از متد ها كافيه اسم متد رو با استفاده از () بنويسيم. كد بالا نيز اسم يك متد به نام ()Person ذكر شده است:
سازنده ها در سي شارپ - Constructors in CSharp
سازنده (Constructor) متدي است هم نام با كلاس كه چه بنويسيم (تايپ كنيم)
و چه ننويسيم بر روي كلاس ها وجود دارد. همانطور كه قبلا هم ديديد من براي
كلاس Person متدي هم نام با كلاس ننوشتم اما مي توانستم از اين متد در
كنار كلمه new استفاده كنيم. كلمه new فقط براي ايجاد كردن يك شيء در
حافظه در كنار نام متد استفاده مي شود. پس دقت داشته باشين كه وقتي ما يك
reference copy از يك شيء تهيه ميكنيم در واقع فقط يك كپي از آدرس حافظه
همان شيء را داريم (مثل 2 ريموت كنترل به يك تلويزويون) , اما وقتي از new
به همراه اسم متد استفاده مي كنيم يك شيء جديد در حافظه داريم.
سازنده پيشفرض - Default Constructor
سازنده پيش فرض يا همان Default Constructor متدي است هم نام با كلاس كه
پارامتر ورودي ندارد و شما به صورت پيش فرض يك ورژن از سازنده ها رو در
كلاستان دارين. به اين معني كه حتي وقتي كلاس شما داراي هيچ عضوي نيست
(مثل اين كلاس Emp ) باز داراي يك متد سازنده يا همان Constructor مي
باشد. البته اين به اين معني نيست كه شما نمي توانيد سازنده ها را تايپ
كنين:
public class Emp
{
}
public class Student
{
public Student()
{
// default constructor
}
}
در هر دو كلاس بالا شما داراي default constructor مي باشد پس مي توانين كه كد هاي زير را تايپ كنين:
Emp e = new Emp();
Student st = new Student();
نكته بسيار مهم استفاده است كه شما مي توانين از Constructor ها داشته
باشيد. دقت كنين كه وقتي شما كدي را داخل block of code يك سازنده از يك
كلاس مي نويسيد مادامي كه از اين كلاس شيء جديد ساخته مي شود كدي كه داخل
constructor نوشته شده نيز اجرا خواهد شد در نتيجه شما با استفاده از
سازنده ها اين توانمندي را خواهيد داشت كه در زمان ساخته شده هر شيء كد مورد نظرتان را اجراء نمائيد.
فرض كنين كه من مي خواهم هر زماني كه يك object از كلاس Emp ساخته شد يك جمله در محيط كنسول چاپ شود كه يك object جديد ساخته شد.
public class Emp
{
public Emp()
{
Console.WriteLine("New Emp Object Created ...");
}
}
Constructor Overloading
در سي شارپ شما اين امكان را داريد كه ورژن هاي متفاوتي از يك متد را
داشته باشين. از آنجايي كه سازنده ها هم به نوعي متد محسوب مي شوند شما مي
توانيد ورژن هاي متفاوتي از سازنده ها را داشته باشين. براي مثال در نظر
بگيرين كه من مي خواهم يك ورژن از سازنده براي كلاس Person بنويسم كه وقتي
از اين كلاس شيء ايجاد مي شود حتما نام و سن فرد ذكر شود. پس براي اينكار
سازنده اي تعريف مي كنم كه داراي دو ورودي , يكي از جنس رشته اي (براي
نام) و ديگري از جنس عددي (براي سن) داشته باشد:
public class Person
{
public Person(string name, int Age)
{
Name = name;
Age = age;
}
public int Age;
public string Name;
}
! دقت داشته باشين كه وقتي شما يك ورژن ديگر از سازنده را مي نويسن
(ورژني به غير از سازنده پيش فرض) در حالتيكه سازنده پيش فرض را تايپ
نكنين ديگر امكان استفاده از سازنده پيش فرض را نداريد.
به همين دليل در صورتيكه شما كد بالا را بنويسين ديگر امكان استفاده از
سازنده پيش فرض كلاس Person وجود نخواهد داشت و اين به اين معني است كه
شما به برنامه نويس اجبار خواهيد كرد كه حتما موقع ساختن شيء از كلاس شما
نام و سن شيء را مشخص كند.
//You will get compile time error if you uncomment the next line
//Person p = new Person();
Person p =new Person("Ali",20);
در صورتيكه امكان ايجاد كردن شيء از اين كلاس بدون مشخص كردن نام و سن را نياز داريد مي توانين سازنده پيش فرض را نيز تايپ نمائيد.
نقش هاي يك برنامه نويس - Programmer 's Role
1. Class Programmer
2. Class Creator
هر برنامه نويس در حين نوشتن كد مي تواند دو نقش داشته باشد و بسيار مهم است كه نقش خود را در هر لحظه بتواند تشخيص دهد.
فرض كنين كه شما در حال نوشتن كلاس Emp هستين :
public class Emp
{
...
در اين حالت شما يك Class Creator مي باشيد. به اين معني كه شما يك كلاس
را ايجاد مي كنين فرقي نمي كند كه شما از اين كلاس استفاده كنين يا كس
ديگري.
در حالتي كه شما در كلاس Programm هستيد و داخل متد Main از كلاس
Empاستفاده مي كنين شما يك Class Programm براي كلاس Emp هستيد يعني از
اين كلاس استفاده مي كنين. دقت كنين كه در همين لحظه شما براي كلاس
Programm يك Class Creator مي باشين.
درك كردن اين نقش ها به شما كمك خواهد كرد كه ديد بهتري نسبت به توليد
كلاس ها داشته باشين و متوجه باشين كه چه چيزي رو در اختيار چه نقشي قرار
مي دهيد.
حالا كه در مورد Constrcutor ها و Method ها صحبت كرديم مي تونيم بگيم كه
تا حدودي كلاس ها رو شناختيم و حالا مي تونيم ادامه مطالبمون در رابطه با
Value Type ها رو پيش ببريم:
Structures in CSharp
Structure ها نوع هاي داده اي هستند شبيه به كلاس ها به اين معنا كه مي
توانند Field و Method و Constructor داشته باشند و حتي در بعضي از موارد
به خاطر نوع رفتاري كه Value Type ها دارند به جاي كلاس ها استفاده شوند.
براي تعريف يك Structure كافيست در جايي از namespace با استفاده از
keyword ي كه به همين منظور ايجاد شده است يعني struct شروع به ايجادش
نمائيم:
public struct Teacher
{
public int Age;
public string Name;
public void Print()
{
Console.WriteLine("Name: {0}, Age: {1}",Name, Age);
}
}
همانطور كه مي بينيم ساختار ظاهري Struct ها كاملا شبيه به كلاس است اما تفاوت اصلي آن ها در رفتارهايشان مي باشد.
در تعريف رفتار هاي كلاس گفتيم
وقتي شما يك شيء از نوع يك كلاس مثل Person ايجاد مي كنين و بعد از آن شيء
كپي تهيه مي كنين فقط آدرس حافظه شيء قبلي به شيء جديد اختصاص يافته و در
حقيقت شما فقط يك شيء داريد.
اما در مورد Struct ها جريان كاملا شبيه به كپي گرفتن از تايپ هاي بدوي (Primitive Types) ها مي باشد. به چند خط كد زير دقت كنين:
Teacher t = new Teacher();
t.Name = "Ali";
t.Age = 44;
Teacher t2 = t;
t2.Name = "Reza";
t.Print();
t2.Print();
به نظر شما خروجي اين چند خط كد چيست؟
به اشكال زير دقت كنين:
نكته بسيار مهم در شكل اول اينست كه اصولا به خاطر Value Type بودن Struct ها هيچ شيء اي در حافظه Heap ايجاد نشده است و فقط دو متغيير در حافظه Stack ايجاد شده است. نكته مهم دوم اينه كه وقتي شما از يك متغيير از نوع Struct كپي مي گيرين تمامي مقادير موجود در آن Struct كپي شده و در متغيير جديد يك كپي از آن مقادير قرار خواهد گرفت. پس در نتيجه تغييراتي كه ما در متغيير دوم يعني t2 داديم برروي متغيير اول يا همان t تاثيري نخواهد داشت.
Constructors in Structures - سازنده ها در ساختار ها
نكته مهم ديگري كه مي توان در مورد Struct ها بيان كرد در مورد سازنده ها در اين جنس است. در پست قبلي در مورد ايجاد سازنده ها در كلاس ها صحبت كرديم و گفتم كه شما مي توانين ورژن هاي مختلفي از سازنده ها را در يك كلاس داشته باشين. اما بايد بگويم كه در مورد Struct ها جريان كمي متفاوت خواهد بود.
نكته اول: شما سازنده پيشفرض را در Struct ها دارين اما امكان تايپ كردن آن را به صورت دستي ندارين. به اين معني كه اگر شما يك Constructor بدون پارامتر در يك Struct تعريف كنين به Compile Time Error بر خورد خواهيد كرد و در حقيقت شما نمي تونين هيچ تغييري در رفتار سازنده پيشفرض Struct ها ايجاد كنين. بايد بدونين كه سازنده پيش فرض در Structureها در حقيقت يك object ايجاد نمي كند بلكه به تمامي متغييرهايي كه داخل Struct شما وجود دارند مقدار پيش فرض را Set مي كند.
Teacher t = new Teacher();
در نتيجه كد بالا فيلد Age مقدار 0 و فيلد Name مقدار "" را كه مقادير پيشفرض int و String هستند را خواهند گرفت.
نكته دوم: در تمامي ورژن هاي سازنده ها بايد تمامي متغيير هاي Struct شما مقدار دهي شوند. در غير اينصورت بازهم Compile Time Error خواهين داشت.
در نتيجه Struct شما مي تواند به اين شكل باشد:
public struct Teacher
{
public int Age;
public string Name;
public void Print()
{
Console.WriteLine("Name: {0},Age: {1}",Name,Age);
}
public Teacher(int age, string Name)
{
Name = name;
Age = age;
}
public Teacher(int age)
{
Age = age;
Name = "";
}
}
در این وبلاگ سعی شده مطالب مفیدی در زمینه ی عنوان وبلاگ گردآوری بشه،تمامی این مطالب در یادگیری بنده تاثیر بسزایی داشته.