خواص (Properties)

property (خصوصیت) استانداردی در جاوا برای دسترسی به اعضای داده‌ای با سطح دسترسی private در داخل یک کلاس می‌باشد. هر property دارای دو بخش می‌باشد، یک بخش جهت مقدار دهی (بلوک set) و یک بخش برای دسترسی به مقدار (بلوک get) یک داده private می‌باشد. property ها باید به صورت public تعریف شوند تا در کلاسهای دیگر نیز قابل دسترسی می‌باشند. در مثال زیر نحوه تعریف و استفاده از property آمده است :

   1: package myfirstprogram;
   2: 
   3: import java.text.MessageFormat;
   4: 
   5: class Person
   6: {
   7:     private String name;
   8:     private int age;
   9:     private double height;
  10: 
  11:     public void setName(String name)     
  12:     {                                    
  13:         this.name = name;                
  14:     }                                    
  15:                                          
  16:     public String getName()              
  17:     {                                    
  18:         return name;                     
  19:     }                                    
  20: 
  21:     public void setAge(int age)          
  22:     {                                    
  23:         this.age = age;                  
  24:     }                                    
  25:                                          
  26:     public int getAge()                  
  27:     {                                    
  28:         return age;                      
  29:     }                                    
  30:       
  31:     public void setHeight(double height) 
  32:     {                                    
  33:         this.height = height;            
  34:     }                                    
  35:                                          
  36:     public double getHeight()            
  37:     {                                    
  38:         return height;                   
  39:     }                                    
  40: 
  41: 
  42:     public Person(String name, int age, double height)
  43:     {
  44:         this.name = name;
  45:         this.age = age;
  46:         this.height = height;
  47:     }
  48: 
  49: }
  50: 
  51: public class MyFirstProgram 
  52: {     
  53:     public static void main(String[] args) 
  54:     {         
  55:         Person person1 = new Person("Jack", 21, 160);
  56:         Person person2 = new Person("Mike", 23, 158);
  57:         
  58:         System.out.println(MessageFormat.format("Name: {0}", person1.getName()));
  59:         System.out.println(MessageFormat.format("Age: {0} years old", person1.getAge()));
  60:         System.out.println(MessageFormat.format("Height: {0}cm", person1.getHeight()));
  61:
  62:         System.out.println(); //Seperator 
  63:         
  64:         System.out.println(MessageFormat.format("Name: {0}", person2.getName()));
  65:         System.out.println(MessageFormat.format("Age: {0} years old", person2.getAge()));
  66:         System.out.println(MessageFormat.format("Height: {0}cm", person2.getHeight()));
  67:                                        
  68: 
  69:         person1.setName("Frank");  
  70:         person1.setAge(19);       
  71:         person1.setHeight(162);      
  72:                                   
  73:         person2.setName("Ronald");
  74:         person2.setAge(25);              
  75:         person2.setHeight(174);      
  76:        
  77:         System.out.println(); //Seperator
  78:         
  79:         System.out.println(MessageFormat.format("Name: {0}", person1.getName()));
  80:         System.out.println(MessageFormat.format("Age: {0} years old", person1.getAge()));
  81:         System.out.println(MessageFormat.format("Height: {0}cm", person1.getHeight()));
  82: 
  83:         System.out.println(); //Seperator                     
  84: 
  85:         System.out.println(MessageFormat.format("Name: {0}", person2.getName()));
  86:         System.out.println(MessageFormat.format("Age: {0} years old", person2.getAge()));
  87:         System.out.println(MessageFormat.format("Height: {0}cm", person2.getHeight()));
  88:     }   
  89: }
Name: Jack
Age: 21 years old
Height: 160cm

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

Name: Frank
Age: 19 years old
Height: 162cm

Name: Ronald
Age: 25 years old
Height: 174cm

در برنامه بالا نحوه استفاده از property آمده است. همانطور که مشاهده می‌کنید در این برنامه ما سه خصوصیت که هر کدام مربوط به اعضای داده‌ای هستند تعریف کرده‌ایم (سه فیلد با سطح دسترسی private).

private string name;
private int age;
private double height;

دسترسی به مقادیر این فیلدها فقط از طریق property های ارائه شده امکان پذیر است.

  11: public void setName(String name)  
  12: {                                    
  13:     this.name = name;              
  14: }                                    
  15:                                      
  16: public String getName()
  17: {                                    
  18:     return name;                   
  19: }                                    
  20: 
  21: public void setAge(int age)        
  22: {                                    
  23:     this.age = age;                
  24: }                                    
  25:                                      
  26: public int getAge()                
  27: {                                   
  28:     return age;                    
  29: }                                    
  30: 
  31: public void setHeight(double height)
  32: {                                    
  33:     this.height = height;           
  34: }                                    
  35:                                      
  36: public double getHeight()           
  37: {                                    
  38:     return height;                  
  39: }                                    

وقتی یک خاصیت ایجاد می‌کنیم، باید سطح دسترسی آن را public تعریف کرده و نوع داده‌ای را که بر می‌گرداند یا قبول می‌کند را مشخص کنیم. به این نکته توجه کنید که نام property ها همانند نام فیلدهای مربوطه می‌باشد با این تفاوت که حرف اول آنها بزرگ نوشته می‌شود. البته قبل از نام آنها کلمات set و get هم نوشته می‌شود. مثلاً برای فیلد name (خط 7) دو متد با نامهای setName و getName (خطوط 19-11) ایجاد شده‌اند. البته یادآور می‌شویم که شباهت نام property ها و فیلدها اجبار نیست و یک قرارداد می‌باشد.

به عنوان مثال به عبارت زیر توجه کنید :

this.name = name;

این عبارت که در خط 13 کد بالا آمده است برای مقداردهی به فیلد name به کار رفته است. this به شئ جاری ایجاد شده از کلاس اشاره دارد، name بعد آن همان فیلد تعریف شده در خط 7 کد ابتدای آموزش و name سمت راست علامت مساوی هم پارامتر تعریف شده در خط 11 است. برای دسترسی به یک خاصیت می‌توانید از علامت دات (.) استفاده کنید.

  58: System.out.println(MessageFormat.format("Name: {0}", person1.getName()));
  59: System.out.println(MessageFormat.format("Age: {0} years old", person1.getAge()));
  60: System.out.println(MessageFormat.format("Height: {0}cm", person1.getHeight()));

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

  69: person1.setName("Frank"); 
  70: person1.setAge(19);
  71: person1.setHeight(162); 

دستورات بالا بخش set مربوط به هر property را فراخوانی کرده و مقادیری به هر یک از فیلدها اختصاص می‌دهد. استفاده از property ها کد نویسی را انعطاف پذیر می‌کند مخصوصاً اگر بخواهید یک اعتبارسنجی برای اختصاص یک مقدار به فیلدها یا استخراج یک مقدار از آنها ایجاد کنید. مثلاً شما می‌توانید یک محدودیت ایجاد کنید که فقط اعداد مثبت به فیلد age (سن) اختصاص داده شود. می‌توانید با تغییر بخش set خاصیت Age این کار را انجام دهید :

  21: public void setAge(int age)
  22: { 
  23:      if (age > 0)     
  24:      {                
  25:        this.age = age;
  26:      }                
  27:      else             
  28:      {                
  29:        this.age = 0;  
  30:      }                
  31: }

حال اگر کاربر بخواهد یک مقدار منفی به فیلد age اختصاص دهد مقدار age صفر خواهد شد. همچنین می‌توان یک property فقط خواندنی (read-only) ایجاد کرد. این property فاقد بخش set است. به عنوان مثال می‌توان یک خاصیت Name فقط خواندنی مانند زیر ایجاد کرد :

public String getName()
{
   return name;
}

در این مورد اگر بخواهید یک مقدار جدید به فیلد name اختصاص دهید با خطا مواجه می‌شوید. نکته دیگری که باید به آن توجه کنید این است که شما می‌توانید برای بخش set یا get سطح دسترسی ایجاد کنید. به تکه کد زیر توجه کنید :

private void setName(String name)     
{                                    
    this.name = name;                
}                                    

public String getName()              
{                                    
    return name;                     
}  

خاصیت Name فقط در خارج از کلاس قابل خواندن است اما متدها فقط داخل کلاس Person می‌توانند مقادیر جدید بگیرند. یک property می‌تواند دارای دو فیلد باشد. به کد زیر توجه کنید :

private String firstName;
private String lastName;

public String getFullName()
{
    return firstName + " " + lastName; 
}

همانطور که در مثال بالا مشاهده می‌کنید یک property فقط خواندنی تعریف کرده‌ایم که مقدار برگشتی آن ترکیبی از دو فیلد firstName و lastName است که به وسیله فاصله از هم جدا شده‌اند.