آشنایی با مفهوم کانستراکتور در زبان برنامه نویسی جاوا

سیده آمین ارمان

کاربر نگاه دانلود
کاربر نگاه دانلود
عضویت
2016/05/10
ارسالی ها
1,730
امتیاز واکنش
20,744
امتیاز
795
محل سکونت
البرز
به نظر می رسد پس از آشنایی با تفاوت مابین Local Variable ها و Field ها در زبان جاوا بتوانیم بهتر مفهوم کانستراکتورها را در زبان برنامه نوسی جاوا درک کنیم. برای همین منظور پروژه ای تحت عنوان Constructor در محیط اکلیپس ایجاد کرده و کلاسی تحت عنوان MyClass به معنی "کلاس من" در آن می سازیم.

چنانچه بخواهیم به طور خلاصه بگوییم که کانستراکتور چیست، بایستی گفت که یک کانستراکتور همانند یک متد است با این تفاوت که نام آن دقیقاً با نام کلاس یکی بوده و از سوی دیگر به هیچ وجه نمی تواند داده ای را return کند (به منظور آشنایی با دستور return به آموزش های گذشته مراجعه فرمایید.) واقعیت دیگری که در مورد کانستراکتورها صدق می کند این است که یک کانستراکتور می تواند هیچ پارامتری نداشته باشند، یک پارامتر داشته و یا حتی بیش از یک پارامتر داشته باشد.

اکنون ببینیم که کاربرد کانستراکتور چیست. در واقع زمانی که ما یک آبجکت از روی کلاسی می سازیم، کانستراکتور آن کلاس فرا خوانده می شود. کار این کانستراکتور این است که Field های آن آبجکت جدید را Initialize کرده یا به عبارت دیگر می سازد. نکته ای که در اینجا می بایست حتما مد نظر قرار داده شود این است که ما برای ساخت یک آبجکت جدید از روی یک کلاس نیاز به یک کانستراکتور داریم و اگر ما این کانستراکتور را ننویسیم، خود کامپایلر در حین ساخت آبجکت یک کانستراکتور که فاقد هرگونه پارامتری باشد را برای ما در حین کامپایل شدن خواهد ساخت. این کانستراکتور تحت عنوان Default Constructor یا کانستراکتور پیش فرض شناخته می شود. کاری که این کانستراکتور انجام می دهد این است که کلیه متغیرهای Field را با مقدار اولیه Default فرا می خواند (مقدار اولیه صفر برای متغیرهای عددی، مقدار false برای متغیر boolean و مقدار null برای مواردی همچون استرینگ ها.)

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

public class MyClass {
String name;
int age;
boolean trueOrFalse;
public void dispaly() {
System.out.println(name);
System.out.println(age);
System.out.println(trueOrFalse);
}
}
در کد فوق همان طور که مشاهده می شود سه Instance Variable یا متغیرهای Field یکی از جنس متغیر عددی، یکی از جنس متغیر boolean و یکی هم از جنس کلاس String تحت عناوین age و trueOrFalse و name به معنی به ترتیب «سن، درست یا غلط و نام» ساخته ایم. سپس یک متد تحت عنوان display به معنی "نمایش بده" ساخته و در آن دستور داده ایم تا Field های ایجاد شده در داخل کلاس را روی صفحه کنسول نمایش دهد.

حال نوبت به ساخت کلاس دیگری می رسد که به منزله نقطه شروع برنامه باشد. به عبارت دیگر این کلاس جدید می بایست دارای متد main باشد. برای این منظور کلاس دیگری تحت عنوان ActionClass به معنی "کلاس عملیاتی" ساخته و در حین ساخت آن گزینه public static void main را تیک می زنیم. پس از ساخت این کلاس، یک آبجکت از روی کلاس MyClass ساخته و نام آن را objectOne به معنی "آبجکت شماره یک" می گذاریم و در نهایت از طریق آبجکت ساخته شده، متد موجود در کلاس MyClass را فرا می خوانیم:

public class ActionClass {
public static void main(String[] args) {
MyClass objectOne = new MyClass();
objectOne.dispaly();
}
}
حال برنامه خود را اجرا می کنیم:

39823fb51f48560b320998e233d95833.jpg


همان طور که در تصویر فوق مشاهده می شود، کامپایلر به صورت خودکار یک Default Constructor برای آبجکت ساخته شده ی ما از روی کلاس MyClass ایجاد می کند و همان طور که قبلا گفته شد کار این کانستراکتور این است که مقادیر پیش فرض را برای Field های کلاس MyClass را ایجاد کند (البته این کانستراکتور از آنجا که در حین کامپایل شدن ساخته می شود، از دید ما مخفی است.) در تصویر فوق مقدار پیش فرض null برای آبجکت ساخته شده از روی کلاس String بوده، مقدار پیش فرض صفر برای متغیر int بوده و مقدار پیش فرض آخر که معادل با false است برای متغیر boolean می باشد.

در حقیقت خود کامپایلر جاوا این کانستراکتور را برای آبجکت ما ساخته است. حال ببینیم کامپایلر به چه شکلی این کانستراکتور را در کلاس ما ایجاد کرده است. برای این منظور کد کلاس MyClass را به شکل زیر تکمیل می کنیم:

public class MyClass {
String name;
int age;
boolean trueOrFalse;
MyClass() {
name = null;
age = 0;
trueOrFalse = false;
}
public void dispaly() {
System.out.println(name);
System.out.println(age);
System.out.println(trueOrFalse);
}
}
همانطور که در کد فوق مشاهده می شود، یک کانستراکتور تحت عنوان MyClass ساخته ایم (پیش از این گفتیم که نحوه ی ساخت کانستراکتور همانند ساخت یک متد است با تفاوت که نام آن می بایست دقیقاً هم نام با کلاس بوده و هیچ گونه مقدار بازگشتی مثل int و double و غیره نمی بایست برای آن تعریف شود.)

اکنون داخل کانستراکتور ساخته شده برای Field های کلاس خود مقدار اولیه تعریف می کنیم. مقدار Default برای استرینگ ها همواره null بوده، برای متغیرهای عددی مثل int همواره صفر بوده و برای متغیر boolean معادل با false می باشد. به طور خلاصه نوشتن و ننوشتن این کانستراکتور هیچ فرقی برای ما نخواهد کرد چرا که کامپایلر این کار را به عهده گرفته است. به عبارت دیگر، اگر ما برای آبجکت جدیدی که می سازیم مقادیر اولیه یی در نظر نگیریم، کامپایلر در حین کامپایل کردن برنامه این کار را به صورت خودکار برای ما انجام خواهد داد. این فرایند در تصویر زیر نشان داده شده است:

699ee9a6dac7adb7a53c1b803ba7731c.jpg


برای این که تست کنیم ببینیم که کامپایلر این کار را به صورت خودکار انجام می دهد یا خیر می توان کانستراکتور ساخته شده را کامنت کرده و برنامه را مجدد اجرا کنیم و خواهیم دید که باز هم همان مقادیر اولیه توسط کامپایلر ایجاد می شوند. هم اکنون می خواهیم تا دیگر به کامپایلر اجازه ندهیم تا مقادیر Default را برای Field ها در نظر گیرد، بلکه خود این مقادیر را تعریف کنیم. برای این منظور کد کلاس MyClass را به شکل زیر تغییر می دهیم:

public class MyClass {
String name;
int age;
boolean trueOrFalse;
MyClass(String myName, int myAge, boolean myTrueOrFalse) {
name = myName;
age = myAge;
trueOrFalse = myTrueOrFalse;
}
public void dispaly() {
System.out.println(name);
System.out.println(age);
System.out.println(trueOrFalse);
}
}
همانطور که در کد فوق ملاحظه می شود، سه پارامتر دقیقا از همان جنـ*ـسی که Field ها هستند برای کانستراکتور در نظر گرفته ایم به نام های myName, myAge, myTrueOrFalse و هر کدام از آن ها را معادل با هم تای خود که از جنس Field است قرار داده ایم. علت این که نام پارامترهای Constructor خود را با نام Field های یکی قرار نداده ایم این است که اگر هر دو نام یکی باشد، کامپایلر در حین کامپایل کردن مقادیر Field ها را مد نظر قرار خواهد داد. کد فوق بدون هیچ مشکلی اجرا خواهد شد اما این در حالی است که راه کاری برای این که نام پارامترها و Field ها یکی باشد نیز وجود دارد و آن هم استفاده از کلید واژه ی this می باشد. برای درک بهتر این موضوع کد فوق را به شکل زیر بازنویسی می کنیم:

public class MyClass {
String name;
int age;
boolean trueOrFalse;
MyClass(String name, int age, boolean trueOrFalse) {
this.name = name;
this.age = age;
this.trueOrFalse = trueOrFalse;
}
public void dispaly() {
System.out.println(name);
System.out.println(age);
System.out.println(trueOrFalse);
}
}
همان طور که ملاحظه می شود کلید واژه ی this را قرار داده سپس یک نقطه می گذاریم و نام Field های مد نظر را پس از نقطه قرار می دهیم و در نهایت یک علامت مساوی قرار داده و نام پارامترهای کانستراکتور خود را پس از آن می نویسیم و در انتها یک علامت ; قرار می دهیم. با این کار به کامپایلر دستور می دهیم که مثلا this.name منظور name یی است که در بدنه ی کلاس تعریف شده است و یا this.age همان age یی است که به عنوان یک Field در بدنه ی کلاس نوشته شده است نه age یی که به عنوان پارامتر ورودی کانستراکتور نظر گرفته شده است. از سوی دیگر نام های name, age, trueOrFalse که پس از علائم مساوی قرار گرفته اند همان پارامترهای کانستراکتور ما هستند.

اکنون پس از آن که مقدار Field های کلاس MyClass را از طریق پارامترهای کانستراکتور که خودمان ایجاد کرده ایم تعیین نمودیم، می توانیم برنامه خود را اجرا کنیم. برای همین منظور به کلاس ActionClass رفته و کد خود را به شکل زیر تکمیل می کنیم:

public class ActionClass {
public static void main(String[] args) {
MyClass objectOne = new MyClass("behzad", 29, true);
objectOne.dispaly();
}
}
اگر خاطرمان باشد در کلاس MyClass زمانیکه کانستراکتور خود را ایجاد می کردیم سه پارامتر به ترتیب از جنس استرینگ، عدد صحیح و بولین ایجاد کردیم. حال در کلاس ActionClass با قرار دادن مقادیری داخل پرانتزها متناظر با جایگاه پارامترها (یعنی اول یک داده از جنس استرینگ و دوم یک داده از جنس عدد صحیح و سوم یک داده از جنس بولین)، می توانیم مقدار اولیه پارامترها را تعیین کرده و بالتبع از آنجا که مقدار پارامترها برابر با مقدار Field ها در نظر گرفته شده است، از این رو مقدار اولیه Field ها تعیین خواهد شد (به طور خلاصه، همان طور که در کد فوق مشاهده می شود مقدار “Behzad” برای پارامتری از جنس استرینگی تحت عنوان name در نظر گرفته شده است و از آنجا که مقدار Field یی تحت عنوان name به صورت this.name برابر با مقدار پارامتر ورودی کانستراکتور قرار داده شده است، پس مقدار “Behzad” به Field کلاس MyClass تحت عنوان name که از جنس کلاس String است اختصاص خواهد یافت. دو پارامتر دیگر را نیز به همین شکل می توان تفسیر کرد.) پس از اجرای برنامه خروجی زیر مشاهده خواهد شد:

5faae1e511cd714e075cf29faed99ee2.jpg


همان طور که می بینیم با موفقیت توانستیم مقدار اولیه ی Field های کلاس اول را مقدار دهی کنیم. اکنون فرض کنیم که از روی کلاس MyClass دو عدد آبجکت داریم، یکی تحت عنوان objectOne و دیگری تحت عنوان objectTwo. برای مقدار دهی هر دوی آن ها کد خود را به شکل زیر تکمیل می کنیم:

public class ActionClass {
public static void main(String[] args) {
MyClass objectOne = new MyClass("behzad", 29, true);
objectOne.dispaly();
MyClass objectTwo = new MyClass("Mohammad Ali", 31, false);
objectTwo.dispaly();
}
}
همان طور که مشاهده می شود، در کد فوق دو آبجکت از روی کلاس MyClass تحت عناوین objectOne و objectTwo به معنی به ترتیب "شیء یک" و "شیء دو" ساخته ایم. از آنجا که می خواهیم آبجکت دوم ما هم دارای مقادیر اولیه ای باشد، سه پارامتر با مقادیر Mohammad Ali و 31 و false را برای آن در نظر می گیریم. حال برنامه را اجرا می کنیم:

ebf39bc5bd2b03f6c190d12c9f95551d.jpg


هر دو آبجکت ساخته شده از روی کلاس MyClass با مقادیر اختصاصی خودشان در پنجره ی کنسول نمایش داده شده اند.
 

برخی موضوعات مشابه

بالا