فصل 13: آشنایی با شی و کلاس و مقداردهی اولیه توسط سازنده ها در جاوا

24 مرداد 1397
constructors-java

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

شی در جاوا

به هر چیزی که دارای وضعیت و رفتار باشد، شی گفته می شود مانند ماشین، خودکار، دورچرخه و غیره. همانطور که گفته شد، شی می تواند منطقی یا فیزیکی باشد (ملموس و غیرملموس). از اشیا غیر ملموس می توان به سیستم بانکی اشاره کرد.

هر شی دارای سه ویژگی می باشد:

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

به عنوان مثال خودکار یک شی است که نامش بیک است، رنگش آبی است و می نویسد. بیک و آبی بودن نشان دهنده وضعیت و نوشتن نشان دهنده رفتار این شی است.

شی یک نمونه ساخته شده از کلاس می باشد. کلاس همانند الگویی است که اشیا از آن ساخته می شود.

تعاریف شی را یکبار دیگر بررسی می کنیم:

  • یک موجودیت دنیای واقعی
  • یک موجودیت موقع اجرای برنامه
  • موجودیتی که دارای رفتار و وضعیت است
  • شی یک نمونه از کلاس است

کلاس در جاوا

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

کلاس‌ها در جاوا می توانند شامل موارد زیر باشند:

  • فیلد
  • متد
  • کانستراکتور یا سازنده (Constructor)
  • بلوک
  • اینترفیس و کلاس داخلی

سینتکس ساخت کلاس:

class <class_name>{  
    field;  
    method;  
}

نمونه متغیر در جاوا

به متغیری که درون کلاس و خارج از متد تعریف شده باشد، نمونه متغیر می گویند. نمونه متغیر در زمان کامپایل حافظه اشغال نمی کند و تنها هنگامی که یک شی ساخته می شود، حافظه اشغال می کند. به همین خاطر، نمونه متغیر خوانده می شود.

متد در جاوا

در جاوا، متد همچون یک تابع می باشد و رفتار یک شی را مشخص می کند. از مزایای متد می توان به استفاده چند باره از کد و بهینه بودن کد اشاره کرد.

کلمه کلیدی new

از کلمه کلیدی new برای اختصاص حافظه هنگام اجرای برنامه استفاده می شود. تمام اشیا در قسمت Heap، حافظه اشغال می کنند.

مثال کلاس و شی: متد main در کلاس

در اینجا کلاس Student ساخته شده است که فیلدهای آن شامل اسم دانش آموز و شماره شناسایی او می باشد. سپس در متد main که در همین کلاس ساخته شده است، یک شی از کلاس Student ساخته می شود که نام این شی S1 می باشد (توجه کنید که نام شی Student که ساخته شده، S1 می باشد، نام خود دانش آموز تعیین نشده است). حالا نام و شماره شناسایی این دانش آموز را چاپ می کنیم.

کد:

class Student{  
 int id;//field or data member or instance variable  
 String name;  
  
 public static void main(String args[]){  
  Student s1=new Student();//creating an object of Student  
  System.out.println(s1.id);//accessing member through reference variable  
  System.out.println(s1.name);  
 }  
}

خروجی:

0 
null

مثال: main خارج از کلاس

در توسعه نرم‌افزار به شکل جدی، معمولا کلاس‌ها ساخته می شوند و از آنها در کلاس دیگری استفاده می شود. در مثال پایین دو کلاس در یک فایل ساخته شده است؛ پیشنهاد می شود که در این مواقع، نام فایل را نام کلاسی بگذارید که کلاس main در آن قرار دارد. حالا همان مثال بالا را دوباره مشاهده می کنیم.

کد:

class Student{  
 int id;  
 String name;  
}  
class TestStudent1{  
 public static void main(String args[]){  
  Student s1=new Student();  
  System.out.println(s1.id);  
  System.out.println(s1.name);  
 }  
}

خروجی:

0 
null

راه های مقداردهی اولیه به شی

3 راه برای مقداردهی اولیه به اشیا در جاوا وجود دارد:

  1. توسط متغیر رفرنس یا متغییر مرجع
  2. توسط متد
  3. توسط کانستراکتور یا سازنده

مثال مقداردهی توسط متغیر رفرنس:

مقداردهی به معنای ذخیره اطلاعات در اشیا می باشد. در مثالی که می بینیم توسط متغیر رفرنس این کار انجام شده است.

کد:

class Student{  
 int id;  
 String name;  
}  
class TestStudent2{  
 public static void main(String args[]){  
  Student s1=new Student();  
  s1.id=101;  
  s1.name="Sonoo";  
  System.out.println(s1.id+" "+s1.name);//printing members with a white space  
 }  
}

خروجی:

101 Sonoo

همچنین می توان چندین شی ساخت و همینکار را تکرار کرد:

کد:

class Student{  
 int id;  
 String name;  
}  
class TestStudent3{  
 public static void main(String args[]){  
  //Creating objects  
  Student s1=new Student();  
  Student s2=new Student();  
  //Initializing objects  
  s1.id=101;  
  s1.name="Sonoo";  
  s2.id=102;  
  s2.name="Amit";  
  //Printing data  
  System.out.println(s1.id+" "+s1.name);  
  System.out.println(s2.id+" "+s2.name);  
 }  
}

خروجی:

101 Sonoo
102 Amit

مثال مقداردهی توسط متد

در این مثال ابتدا اشیا ساخته می شوند، سپس به کمک دو متد insertRecord و displayInformation اطلاعات را وارد اشیا می کنیم و سپس نمایش می دهیم.

کد:

class Student{  
 int rollno;  
 String name;  
 void insertRecord(int r, String n){  
  rollno=r;  
  name=n;  
 }  
 void displayInformation(){System.out.println(rollno+" "+name);}  
}  
class TestStudent4{  
 public static void main(String args[]){  
  Student s1=new Student();  
  Student s2=new Student();  
  s1.insertRecord(111,"Karan");  
  s2.insertRecord(222,"Aryan");  
  s1.displayInformation();  
  s2.displayInformation();  
 }  
}

خروجی:

111 Karan
222 Aryan

کلاس ها در جاوا

همانطور که در شکل مشاهده می کنید، اشیا درون بخش heap حافظه هستند و S1 و S2 هر دو متغیرهای رفرنسی هستند که برای به اشیا درون حافظه اشاره می کنند.

مقداردهی توسط کانستراکتر را در ادامه خواهیم آموخت.

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

کلاس Employee:

کد:

class Employee{  
    int id;  
    String name;  
    float salary;  
    void insert(int i, String n, float s) {  
        id=i;  
        name=n;  
        salary=s;  
    }  
    void display(){System.out.println(id+" "+name+" "+salary);}  
}  
public class TestEmployee {  
public static void main(String[] args) {  
    Employee e1=new Employee();  
    Employee e2=new Employee();  
    Employee e3=new Employee();  
    e1.insert(101,"ajeet",45000);  
    e2.insert(102,"irfan",25000);  
    e3.insert(103,"nakul",55000);  
    e1.display();  
    e2.display();  
    e3.display();  
}  
}

خروجی:

101 ajeet 45000.0
102 irfan 25000.0
103 nakul 55000.0

کلاس Rectangle:

کد:

class Rectangle{  
 int length;  
 int width;  
 void insert(int l, int w){  
  length=l;  
  width=w;  
 }  
 void calculateArea(){System.out.println(length*width);}  
}  
class TestRectangle1{  
 public static void main(String args[]){  
  Rectangle r1=new Rectangle();  
  Rectangle r2=new Rectangle();  
  r1.insert(11,5);  
  r2.insert(3,15);  
  r1.calculateArea();  
  r2.calculateArea();  
}  
}

خروجی:

55 
45

راه های ساخت شی

در جاوا راه‌های متنوعی برای ساخت اشیا وجود دارد از جمله:

  • با استفاده از کلمه کلیدی new
  • با متد() newInstance
  • با متد clone ()
  • به کمک Deserialization
  • با استفاده از فکتوری متد

در ادامه طرز ساخت اشیا با این روش ها را خواهیم آموخت.

شی ناشناس

اشیا ناشناس به اشیایی می گویند که اسم ندارند. معمولا از شی ناشناس هنگام ساخت اشیایی که تنها برای یکبار مورد استفاده قرار می گیرند، استفاده می شود.

new Calculation();//anonymous object

صدا زدن متد از طریق رفرنس

Calculation c=new Calculation();  
c.fact(5);

صدا زدن متد توسط شی ناشناس

new Calculation().fact(5);

حال بگذارید که مثال کامل از اشیا ناشناس ببینیم:

کد:

class Calculation{  
 void fact(int  n){  
  int fact=1;  
  for(int i=1;i<=n;i++){  
   fact=fact*i;  
  }  
 System.out.println("factorial is "+fact);  
}  
public static void main(String args[]){  
 new Calculation().fact(5);//calling method with anonymous object  
}  
}

خروجی:

Factorial is 120

ساخت چندین شی از یک نوع

همانطور که در بحث متغیرهای اولیه داریم و دیدیم

int a=10, b=20;

می توان متغیرهای رفرنس‌دار هم به همین شکل ایجاد کرد.

Rectangle r1=new Rectangle(), r2=new Rectangle();//creating two objects

کد:

class Rectangle{  
 int length;  
 int width;  
 void insert(int l,int w){  
  length=l;  
  width=w;  
 }  
 void calculateArea(){System.out.println(length*width);}  
}  
class TestRectangle2{  
 public static void main(String args[]){  
  Rectangle r1=new Rectangle(),r2=new Rectangle();//creating two objects  
  r1.insert(11,5);  
  r2.insert(3,15);  
  r1.calculateArea();  
  r2.calculateArea();  
}  
}

خروجی:

55 
45

یک مثال واقعی‌تر از حساب‌ها:

کد:

class Account{  
int acc_no;  
String name;  
float amount;  
void insert(int a,String n,float amt){  
acc_no=a;  
name=n;  
amount=amt;  
}  
void deposit(float amt){  
amount=amount+amt;  
System.out.println(amt+" deposited");  
}  
void withdraw(float amt){  
if(amount<amt){  
System.out.println("Insufficient Balance");  
}else{  
amount=amount-amt;  
System.out.println(amt+" withdrawn");  
}  
}  
void checkBalance(){System.out.println("Balance is: "+amount);}  
void display(){System.out.println(acc_no+" "+name+" "+amount);}  
}  
  
class TestAccount{  
public static void main(String[] args){  
Account a1=new Account();  
a1.insert(832345,"Ankit",1000);  
a1.display();  
a1.checkBalance();  
a1.deposit(40000);  
a1.checkBalance();  
a1.withdraw(15000);  
a1.checkBalance();  
}}

خروجی:

832345 Ankit 1000.0
Balance is: 1000.0
40000.0 deposited
Balance is: 41000.0
15000.0 withdrawn
Balance is: 26000.0

کانستراکتور یا سازنده در جاوا

در جاوا، کانستراکتور بلوکی از کد مشابه متد می باشد که هنگام ساختن شی از کلاس و تخصیص حافظه به آن صدا زده می شود. از این متد معمولا برای مقداردهی اولیه به اشیا استفاده می شود.

چه موقع کانستراکتور اجرا می شود؟

هر زمان که یک شی را به کمک کلمه کلیدی new می سازید، حداقل یک کانستراکتور صدا زده می شود که کانستراکتور پیش‌فرض می باشد.

توجه کنید که در صورتی که برای کلاس خود کانستراکتور نسازید، جاوا به طور پیش فرض کانستراکتوری می سازد که تمام فیلدها مقدار اولیه خود را دارند.

قوانین ساخت کانستراکتور

به طور کلی دو قانون هنگام ساخت کانستراکتور وجود دارد:

  1. نام کانستراکتور با نام کلاس دقیقا یکی باشد.
  2. در کانستراکتور نباید همانند متد نوع داده بازگشتی مشخص شود.

انواع کانستراکتورهای جاوا

  1. کانستراکتور پیش‌فرض یا بدون آرگومان
  2. کانستراکتور چندپارامتری که دارای آرگومان ورودی می باشد.

کانستراکتورها در جاوا

کانستراکتور پیش‌فرض جاوا

اگر کانستراکتور پارامتر نداشته باشد، کانستراکتور پیش‌فرض یا Default نام می گیرد.

سینتکس:

<class_name>(){}

مثال:

class Bike1{  
Bike1(){System.out.println("Bike is created");}  
public static void main(String args[]){  
Bike1 b=new Bike1();  
}  
}

خروجی:

Bike is created

استفاده از کانستراکتور (سازنده ها) در جاوا

اگر برای کلاس خودتان کانستراکتور ننویسید، جاوا خود یک کانستراکتور پیش‌فرض برای کلاس در نظر می گیرد.

سوال: هدف از کانستراکتور پیش‌فرض چیست؟

کانستراکتور پیش فرض مقادیر اولیه را به داده ها اختصاص می دهد مانند صفر یا null.

مثال:

class Student3{  
int id;  
String name;  
  
void display(){System.out.println(id+" "+name);}  
  
public static void main(String args[]){  
Student3 s1=new Student3();  
Student3 s2=new Student3();  
s1.display();  
s2.display();  
}  
}

خروجی:

0 null
0 null

در این مثال جاوا خود کانستراکتور پیش فرض را برای ما می سازد.

کانستراکتور پارامتری در جاوا

در مثال زیر، کلاس Student دارای یک کانستراکتور دو پارامتری می باشد. تعداد پارامترهای یک کانستراکتور محدودیت ندارد.

مثال:

class Student4{  
    int id;  
    String name;  
      
    Student4(int i,String n){  
    id = i;  
    name = n;  
    }  
    void display(){System.out.println(id+" "+name);}  
   
    public static void main(String args[]){  
    Student4 s1 = new Student4(111,"Karan");  
    Student4 s2 = new Student4(222,"Aryan");  
    s1.display();  
    s2.display();  
   }  
}

خروجی:

111 Karan
222 Aryan

اورلود کانستراکتورها در جاوا

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

اورلود کانستراکتور به این معناست که یک کلاس دارای چندین کانستراکتور باشد. کامپایلر با توجه به نوع و تعداد پارامترهای کانستراکتور می تواند تشخیص دهد که از کدام کانستراکتور باید استفاده کند.

مثال:

class Student5{  
    int id;  
    String name;  
    int age;  
    Student5(int i,String n){  
    id = i;  
    name = n;  
    }  
    Student5(int i,String n,int a){  
    id = i;  
    name = n;  
    age=a;  
    }  
    void display(){System.out.println(id+" "+name+" "+age);}  
   
    public static void main(String args[]){  
    Student5 s1 = new Student5(111,"Karan");  
    Student5 s2 = new Student5(222,"Aryan",25);  
    s1.display();  
    s2.display();  
   }  
}

خروجی:

111 Karan 0
222 Aryan 25

تفاوت متد و کانستراکتور در جاوا

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

 

کانستراکتور کپی در جاوا

در جاوا همانند سی‌ پلاس‌ پلاس کانستراکتور کپی وجود ندارد اما می توان مقادیر یک شی را به دیگری منتقل کرد.

از راه های اینکار می توان به موارد زیر اشاره کرد:

  • استفاده از کانستراکتور
  • با مساوی قرار دادن مقادیر دو شی
  • استفاده از متد clone()

نحوه اینکار را با استفاده از کانستراکتور می بینیم:

class Student6{  
    int id;  
    String name;  
    Student6(int i,String n){  
    id = i;  
    name = n;  
    }  
      
    Student6(Student6 s){  
    id = s.id;  
    name =s.name;  
    }  
    void display(){System.out.println(id+" "+name);}  
   
    public static void main(String args[]){  
    Student6 s1 = new Student6(111,"Karan");  
    Student6 s2 = new Student6(s1);  
    s1.display();  
    s2.display();  
   }  
}

خروجی

111 Karan
111 Karan

کپی کردن مقادیر بدون کانستراکتور

با مساوی قرار دادن مقادیر دو شی نیز می توان اینکار را به گونه ای که نیاز به کانستراکتور نباشد انجام داد.

class Student7{  
    int id;  
    String name;  
    Student7(int i,String n){  
    id = i;  
    name = n;  
    }  
    Student7(){}  
    void display(){System.out.println(id+" "+name);}  
   
    public static void main(String args[]){  
    Student7 s1 = new Student7(111,"Karan");  
    Student7 s2 = new Student7();  
    s2.id=s1.id;  
    s2.name=s1.name;  
    s1.display();  
    s2.display();  
   }  
}

خروجی

111 Karan
111 Karan

سوال: آیا کانستراکتور مقداری برمی گرداند؟

با اینکه ما آنرا مشخص نمی کنیم، اما نمونه ساخته شده از کلاس را بازمی‌گرداند.

سوال: آیا کانستراکتور کار دیگری غیر از مقداردهی اولیه انجام می دهد؟

بله؛ همانطور که گفته شد کانستراکتور همانند متد می باشد پس کارهایی همچون شروع یک ریسه جدید، ساخت شی و غیره را می توان در آن انجام داد.

نویسنده شوید
دیدگاه‌های شما (3 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

زهرا
06 اردیبهشت 1399
سلام من يه سؤال پيش اومد برام اگه چه جوري بفهميم چندتا شي از يك كلاس ساخته شده؟ اگر تعداد شي ها زياد باشه و هدف ها همين تعداد شي هاي ساخته شده باشه؟؟؟

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

Mahdi
15 شهریور 1398
با سلام واقعا کارتون بیسته خیلی جزعیات رو من که الان چندوقته جاوا کار میکنم نمیدونستم(کل دوره منظورمه) بسیار جامع هست ،نتونستم خودمو قانع کنم نظر نذارم،موفق باشید

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

omid
31 خرداد 1398
سلام ممنون از شما مطالب تون فوق العاده س من برای یک موضوع کلی جستجو می کنم حتی کتاب می خونم ولی به کاملی بیان شما نمی رسه خیلی ممنون از زحمات شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.