سازنده

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

   1: package myfirstprogram;
   2: 
   3: import java.text.MessageFormat;
   4: 
   5: class Person
   6: {           
   7:     public String name;  
   8:     public int age; 
   9:     public double height; 
  10:     
  11:     //Explicitly declare a default constructor
  12:     public Person()  
  13:     {                 
  14:     }                 
  15:                                                           
  16:     //Constructor that has 3 parameters  
  17:     public Person(String n, int a, double h) 
  18:     {                                         
  19:         name = n;                             
  20:         age = a;                             
  21:         height = h;                           
  22:     }                                        
  23:        
  24:     public void ShowInformation() 
  25:     {
  26:         System.out.println(MessageFormat.format("Name: {0}", name)); 
  27:         System.out.println(MessageFormat.format("Age: {0} years old", age));     
  28:         System.out.println(MessageFormat.format("Height: {0}cm", height));       
  29:     }                                                     
  30: } 
  31: 
  32: public class MyFirstProgram 
  33: {     
  34:     public static void main(String[] args) 
  35:     {
  36:         Person firstPerson = new Person(); 
  37:         Person secondPerson = new Person("Mike", 23, 158);
  38:    
  39:         firstPerson.name = "Jack"; 
  40:         firstPerson.age = 21;  
  41:         firstPerson.height = 160;   
  42:         firstPerson.ShowInformation();  
  43:    
  44:         System.out.println(); //Seperator  
  45:      
  46:         secondPerson.ShowInformation();
  47:     }   
  48: }
Name: Jack
Age: 21 years old
Height: 160cm

Name: Mike
Age: 23 years old
Height: 158cm

همانطور که مشاهده می‌کنید در مثال بالا دو سازنده را به کلاس Person اضافه کرده‌ایم. یکی از آنها سازنده پیشفرض (خطوط 14-12) و دیگری سازنده‌ای است که سه آرگومان قبول می‌کند (خطوط 21-19).
به این نکته توجه کنید که سازنده درست شبیه به یک متد است با این تفاوت که

  • نه مقدار برگشتی دارد و نه از نوع void است.
  • نام سازنده باید دقیقاً شبیه نام کلاس باشد.

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

Person firstPerson = new Person();
Person secondPerson = new Person("Mike", 23, 158);

در اولین نمونه ایجاد شده از کلاس Person از سازنده پیشفرض استفاده کرده‌ایم چون پارامتری برای دریافت آرگومان ندارد. در دومین نمونه ایجاد شده، از سازنده‌ای استفاده می‌کنیم که دارای سه پارامتر است. کد زیر تأثیر استفاده از دو سازنده مختلف را نشان می‌دهد :

firstPerson.name = "Jack";
firstPerson.age = 21;
firstPerson.height = 160;
firstPerson.ShowInformation();

System.out.println(); //Seperator

secondPerson.ShowInformation();

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

اختصاص مقادیر پیشفرض به سازنده پیشفرض

در مثالهای قبلی یک سازنده پیشفرض با بدنه خالی نشان داده شد. شما می‌توانید به بدنه این سازنده پیشفرض کدهایی اضافه کنید. همچنین می‌توانید مقادیر پیشفرضی به فیلدهای آن اختصاص دهید.

public Person()
{
   this.name = "No Name";
   this.age = 0;
   this.height = 0;
}

همانطور که در مثال بالا می‌بینید سازنده پیشفرض ما چیزی برای اجرا دارد. اگر نمونه‌ای ایجاد کنیم که از این سازنده پیشفرض استفاده کند، نمونه ایجاد شده مقادیر پیشفرض سازنده پیشفرض را نشان می‌دهد.

Person person1 = new Person();

person1.ShowInformation();
Name: No Name
Age: 0 years old
Height: 0cm

استفاده از کلمه کلیدی this

راهی دیگر برای ایجاد مقادیر پیشفرض استفاده از کلمه کلیدی this است. مثال زیر اصلاح شده مثال قبل است و نحوه استفاده از 4 سازنده با تعداد پارامترهای مختلف را نشان می‌دهد.

   1: package myfirstprogram;
   2: 
   3: import java.text.MessageFormat;
   4: 
   5: class Person
   6: {                                                          
   7:     public String name;                                   
   8:     public int age;
   9:     public double height;
  10:  
  11:     public Person()
  12:     { 
  13:         this.name = "No Name";
  14:         this.age = 0;
  15:         this.height = 0;
  16:     } 
  17:      
  18:     public Person(String n)
  19:     { 
  20:         this.name = n;
  21:     }  
  22:      
  23:     public Person(String n, int a) 
  24:     {
  25:         this.name = n;
  26:         this.age = a;
  27:     }
  28:   
  29:     public Person(String n, int a, double h) 
  30:     {                                                      
  31:         this.name = n;
  32:         this.age = a;
  33:         this.height = h;
  34:     }                                                      
  35:      
  36:     public void ShowInformation()
  37:     {  
  38:         System.out.println(MessageFormat.format("Name: {0}", name));
  39:         System.out.println(MessageFormat.format("Age: {0} years old", age)); 
  40:         System.out.println(MessageFormat.format("Height: {0}cm\n", height));
  41:     }   
  42: }  
  43: 
  44: public class MyFirstProgram 
  45: {     
  46:     public static void main(String[] args) 
  47:     {         
  48:         Person firstPerson  = new Person(); 
  49:         Person secondPerson = new Person("Jack");
  50:         Person thirdPerson  = new Person("Mike", 23);       
  51:         Person fourthPerson = new Person("Chris", 18, 152);
  52:                                                            
  53:         firstPerson.ShowInformation();  
  54:         secondPerson.ShowInformation();
  55:         thirdPerson.ShowInformation();
  56:         fourthPerson.ShowInformation(); 
  57:     }   
  58: }
Name: No Name
Age: 0 years old
Height: 0cm

Name: Jack
Age: 0 years old
Height: 0cm

Name: Mike
Age: 23 years old
Height: 0cm

Name: Chris
Age: 18 years old
Height: 152cm

ما چهار سازنده بری اصلاح کلاسمان تعریف کرده‌ایم (خطوط 11، 18، 25، 32). شما می‌توانید تعداد زیادی سازنده برای مواقع لزوم در کلاس داشته باشید. اولین سازنده یک سازنده پیشفرض است. دومین سازنده یک پارامتر از نوع رشته دریافت می‌کند. سومین سازنده دو پارامتر و چهارمین سازنده سه پارامتر می‌گیرد. به چارمین سازنده در خطوط 37-32 توجه کنید. سه سازنده دیگر به این سازنده وابسته هستند. در خطوط 16-11 یک سازنده پیشفرض بدون پارامتر تعریف شده است. به کلمه کلیدی this توجه کنید. این کلمه کلیدی به شما اجازه می‌دهد که یک سازنده دیگر موجود در داخل کلاس را فراخوانی کنید. مقادیر پیشفرضی به فیلدها از طریق سازنده پیشفرض اختصاص می‌دهیم.
چون ما سه مقدار پیشفرض برای فیلدها بعد از کلمه کلیدی this سازنده پیشفرض (خطوط 15-13) در نظر گرفته‌ایم، در نتیجه سازنده‌ای که دارای سه پارامتر است (چهارمین سازنده) فراخوانی شده و سه آرگومان به پارامترهای آن ارسال می‌شود. کدهای داخل بدنه چهارمین سازنده اجرا می‌شوند و مقادیر پارامترهای آن به هر یک از اعضای داده‌ای یه همان فیلدهای تعریف شده در خطوط 9-7 اختصاص داده می‌شود. اگر کدی در داخل بدنه سازنده پیشفرض بنویسیم قبل از بقیه کدها اجرا می‌شود. دومین سازنده (خطوط 23-18) به یک آرگومان نیاز دارد که همان فیلد name کلاس Person است.
وقتی این پارامتر با یک مقدار رشته‌ای پر شد، سپس به پارامترهای سازنده چهارم ارسال شده و در کنار دو مقدار پیشفرض دیگر (0 برای age و 0 برای height) قرار می‌گیرد. در خط 30-25 سومین سازنده تعریف شده است که بسیار شبیه دومین سازنده است با این تفاوت که دو پارامتر دارد. مقدار دو پارامتر سومین سازنده به اضافه‌ی یک مقدار پیشفرض صفر برای سومین آرگومان، به چهارمین سازنده با استفاده از کلمه کلیدی this ارسال می‌شود.

  51: Person firstPerson  = new Person(); 
  52: Person secondPerson = new Person("Jack");
  53: Person thirdPerson  = new Person("Mike", 23);      
  54: Person fourthPerson = new Person("Chris", 18, 152);

همانطور که مشاهده می‌کنید با ایجاد چندین سازنده برای یک کلاس، چندین راه برای ایجاد یک شیء بر اساس داده‌هایی که نیاز داریم به وجود می‌آید. در مثال بالا 4 نمونه از کلاس Person ایجاد کرده‌ایم و چهار تغییر در سازنده آن به وجود آورده‌ایم. سپس مقادیر مربوط به فیلدهای هر نمونه را نمایش می‌دهیم. یکی از موراد استفاده از کلمه کلیدی this به صورت زیر است. فرض کنید نام پارامترهای متد کلاس شما یا سازنده، شبیه نام یکی از فیلدها باشد.

public Person(string name, int age, double height)
{
   name = name;
   age = age;
   height = height;
}

این نوع کدنویسی ابهام بر انگیز است و کامپایلر نمی‌تواند متغیر را تشخیص داده و مقداری به آن اختصاص دهد. اینجاست که از کلمه کلیدی this استفاده می‌کنیم.

public Person(string name, int age, double height)
{
   this.name = name;
   this.age = age;
   this.height = height;
}

قبل از هر فیلدی کلمه کلیدی this را می‌نویسیم و نشان می‌دهیم که این همان چیزی است که می‌خواهیم به آن مقداری اختصاص دهیم. کلمه کلیدی this ارجاع یک شیء به خودش را نشان می‌دهد.