شي گرايي و پياده سازي كلاس

جمعه ، 28 مرداد 1390 ، 11:56 مدیریت کل سایت
چاپ

به نام خدا

مفهوم شی گرایی

کاربرد استفاده از شی گرایی و کلاس

پیاده سازی اولیه کلاس

عضو خصوصی (private) و عضو عمومی (public)

نحوه تعریف اعضای private و public

پیاده سازی کلاس با استفاده از مثال ماشین

محل تعریف کلاس در یک برنامه کامل

نحوه تعریف تابع در بیرون از کلاس

متغیر static

تابع static در کلاس

نحوه استفاده از یک کلاس و ساختن شی

آرایه ای از اشیا

سازنده ها (Constructor)

مخرب ها (Distructor)


مفهوم شی گرایی

زبان هایی مثل ++C به عنوان زبان های شی گراء شناخته می شوند. این خصوصیت به خاطر امکان پیاده سازی شی گرایی در آن می باشد. برای درک مفهوم شی گرایی به مثال زیر توجه کنید:

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

در مثال بالا همان طور که مشخص است وجه مشترک تمام دانشجویان، دانشگاه است و هر دانشجو به طور جداگانه از امکانات آن استفاده می کند. به موارد و رفتارهای مشترک (در این مثال دانشگاه) کلاس (Class) و به هر مورد مشترک در یک class یک فیلد(field) یا data member و به هر رفتار مشترک، تابع عضو کلاس یا Method member گویند.

همچنین به هر چیز یا شی ای که از class استفاده می کند(در این مثال دانشجو) یک شی (Object) می گویند. به این مفهوم، مفهوم شی گرایی گویند.

 


 

کاربرد استفاده از شی گرایی و کلاس:

همان طور که در مفهوم شی گرایی گفته شده کاربرد کلاس ها بسیار گسترده است و کار را برای برنامه نویسی بسیار آسان می کند. اگر خاطرتان باشد در آموزش توابع گفتیم از توابع استفاده می کنیم چراکه برنامه نویسی را آسان و برنامه ی ما را کوتاه و مدیریت آن را آسان می کند. برای بیان این موضوع  که استفاده از کلاس کار را بسیار آسان تر می کند به مثال زیر توجه کنید:

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

راه اول اینکه به طور معمولی به تعداد مولفه های هر ماشین یک متغیر تعریف کنیم و برای هر متغیر نیز دستوراتی را بنویسیم. (در بخش تابع آموختیم که این راه بسیار نامناسب می باشد)

راه دوم اینکه باز هم برای هر ماشین به تعداد مولفه هایش متغیر تعریف کنیم و برای مجموعه متغیر ها تابعی بنویسیم که رفتار آن را توجیه کند. با اینکه این راه نسبت به راه اول مناسب تر است اما اگر دقت کنید اگر تعداد مولفه های هر ماشین 20 عدد باشد و تعداد رفتار های آن نیز 5 عدد باشد نیاز به 20 متغیر و 5 تابع داریم. در این صورت اگر 30 عدد ماشین در این بازی طراحی شده باشد نیاز به 600 متغیر و 5 تابع داریم. به این منظور راه حل سومی ارائه می دهیم که بیان گر کاربرد کلاس می باشد.

راه حل سوم که مناسب ترین راه حل است و گاهی هزاران خط کد را به کمترین حد ممکن تبدیل می کند استفاده از کلاس می باشد. در مثال راه حل دوم(مثال ماشين)،  با استفاده از کلاس برای هر شی 20 متغیر و 5 تابع تعریف می کنیم و هر بار که شی ای را به این کلاس نسبت می دهیم، در واقع متغیرها و توابع را نیز به آن نسبت می دهیم. در این صورت برای 30 عدد ماشین تنها به 20 متغیر، 5 تابع و 30 عدد شی نیاز داریم.

 


 

پیاده سازی اولیه کلاس

در کلاس ها همان طور که گفته شد به یک سری data member و یک سری method member  نیاز داریم. در کلاس این اجزا را  به صورت زیر پیاده سازی می نماییم.

class اسم کلاس{

//data member

//method member

};

دقت شود که بعد از آکولاد بسته از یک سمیکالن ; استفاده شده است.

 


 

عضو خصوصی (private) و عضو عمومی (public):

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

از طرفی دیگر امکان دارد بعضی از فیلدها و توابع به عنوان اعضای کمکی مورد استفاده قرار گیرند و یا به هر دلیلی نخواهیم که برنامه نویس در خارج از کلاس به طور مستقیم به آن ها دسترسی داشته باشد (مثلاً به دلیل امنیت) در این صورت اعضا را به صورت خصوصی یا private تعریف می کنیم.

 


 

نحوه تعریف اعضای private و public:

وقتی شما کلاسی را طراحی می کنید، اعضا به صورت پیش فرض به حالت خصوصی یا همان private تعریف می شوند. برای آن که اعضا را به حالت public در بیاورید، در ابتدای خط public را به صورت زیر می نویسیم:

public:

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

private:

در اينجا نيز تمام عباراتي كه بعد از اين عبارت نوشته مي شود به صورت private در نظر گرفته مي شود.


 

پیاده سازی کلاس با استفاده از مثال ماشین:

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

class car{
int degree;
public:
int speed;
char model[20];
int year;
char color[10];

bool degree(int degr){
degree=degr;
if(speed>100 && degree>60)
return false;
else
return true;
}//end degree
};//end class

تحلیل مثال: در کلاس ماشین نوشته شده در این برنامه 5 عدد data member و یک تابع یا همان method member برای ماشین در نظر گرفته شده است. که از 5 عدد data member، یکی به عنوان عضو خصوصی و چهار تای دیگر به عنوان اعضای عمومی در نظرگرفته شده اند. کاربرد هر عضو به صورت زیر است:

int deg: این عضو به عنوان عضو کمکی استفاده شده که در تابع از آن استفاده می شود و محتوای آن شیب زمین می باشد. البته اين متغير را به صورت مستقيم نيز می توان  از كاربر گرفت، اما به منظور آموزش این کار را نکردیم.

int speed: این عضو به عنوان عضوی عمومی استفاده شده و محتوای آن شامل سرعت ماشین می باشد.

این عضو یک رشته کارکتری است که بیان گر کارخانه سازنده ماشین استchar model[20]

int year این فیلد سال تولید ماشین را مشخص می کند.

[char color[10 این آرایه کارکتری دارای محتوی رنگ ماشین است.

(bool degree(int deg چند نکته در مورد این عضو قابل توجه است. یکی اینکه این تابع با نام یکی از اعضای کلاس ساخته شده است. هدف از این کار این بود که بدانید می تواند تابع را به نام اعضا ساخت. شاید از خود بپرسید که در هنگام استفاده، کامپایلر چگونه متوجه می شود که شما از فیلد استفاده کرده اید یا از تابع. همانطور که در بخش توابع نیز گفتیم، نحوه فراخوانی این دو با هم متفاوت است، بنابراین کامپایلر بدون هیچ مشکلی متوجه منظور شما می شود. نحوه استفاده از اعضا در یک کلاس را در ادامه بیان می کنیم. نكته دوم اینکه توابع استفاده شده در کلاس نیز مانند توابع دیگر می توانند دارای ورودی باشند. در این صورت در هنگام فراخوانی تابع عضو کلاس، می بایست مقدار ورودی آن نیز مشخص شود. این تابع مقداری boolian یا همان درست یا غلط را بر می گرداند. اگر غلط باشد یعنی اینکه ماشین واژگون می شود و اگر درست باشد یعنی اینکه می تواند به راه خود ادامه دهد.

 


 

محل تعریف کلاس در یک برنامه کامل:

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

1. سرفایل ها یا همان headerها

2.using namespace std

3.تعریف وپیاده سازی کلاس ها

4. استفاده از main

همان طور که در توابع نیز می توانستیم تنها اعلان تابع را در بالای mian بنویسیم و بعد از main پیاده سازی آن را بیاوریم. در مورد کلاس ها هم می توانیم همین کار را انجام دهیم. اعلان یا declared کلاس به صورت زیر است:

class اسم کلاس ;

بعد از main نیز کلاس را به صورت معمولی پیاده سازی می نماییم.

 


 

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

گاهی برای خلاصه نویسی نیاز است که توابع آن را در بیرون از کلاس پیاده سازی نماییم. برای این کار در داخل کلاس تابع را اعلان می نماییم. (این کار در توابع بیان شده است). سپس در بیرون از کلاس به صورت زیر تابع را تعریف می نماییم:

(پارامترهای ورودی) اسم تابع::اسم کلاس    نوع خروجی

بین اسم کلاس و اسم تابع از دو عدد : کنار هم استفاده شده است.

class example{
...
int f();
...
};//end example

int example::f(){
...
}//end f

 

متغیر static:

همانطور که متوجه شدید هر فیلد از کلاس برای هر شی از کلاس به صورت جداگانه تخصیص پیدا می کند. یعنی فیلد color در مثال ماشین برای هر شی متفاوت است و دسترسی به color یک شی از شی دیگر امکان پذیر نیست. امکان دارد نیاز باشد متغیری در کلاس تعریف شود که مقدار آن برای تمام اعضای کلاس یکسان باشد و تغییر در آن باعث تغییر کلی آن شود. به چنین متغیری متغیر static می گویند. سه نکته در این قسمت قابل توجه است:

الف) برای تعریف آن در داخل کلاس به صورت زیر عمل می کنیم:

static اسم خروجی   نوع خروجی ;

class example{
...
static int a;
...
};

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

اسم خروجی::اسم کلاس     نوع خروجی ;

class example{
...
static int a;
...
};//end example

int example::a=2;

ج) برای کار با آن باید از توابع static استفاده نمود که در قسمت بعدی در مورد آن توضیح می دهیم.

 


 

تابع static در کلاس

تابع static در مواردی به کار می رود که قصد استفاده با عضوی Static را داشته باشید. البته غیر از آن نیز می توان تابع را به این صورت تعریف کرد اما کاری بیهوده است. نحوه تعریف تابع static به صورت زیر است.

static  اسم تابع   نوع خروجی(...);

class example{
public:
static int a;
static void f(int n){
a=n;
}//end f
};//end class
int example::a;

 


 

نحوه استفاده از یک کلاس و ساختن شی

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

;اسم شی   اسم کلاس

class test{
int b;
public:
static int a;
int c[20];

static void f(){
a++;
}//end f

int f(int n){
b=n;
return (b);
}//end f
};//end class
int test::a;


int main(){
test obj;
return 0;
}

به این صورت یک شی از کلاس test به اسم obj ساخته ایم. این اسم می تواند کاملاً دلخواه باشد. برای استفاده از اعضای کلاس (چه فیلدها و چه توابع) ابتدا اسم شی ساخته شده را می آوریم، سپس مقابل آن یک نقطه یا همان دات (.) قرار می دهیم و سپس اسم عضو را می نویسیم. برای مثال در ادامه برنامه بالا برای دسترسی به اعضای کلاس به صورت زیر عمل می کنیم.

int main(){
test obj;
obj.a=6;
obj.c[3];
obj.c[4];
obj.f();
obj.f(2);
}

همان گونه که مشاهده می کنید نمی توان از عضو b به طور مستقیم استفاده کرد چرا که این عضو به صورت private تعریف شده است. برای دسترسی به آن تابعی به اسم (f(int n تعریف نموده ایم که مقدار n را در b می ریزد.

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

 


 

آرایه ای از اشیا:

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

int main(){
test obj[5];
obj[0].f();
obj[0].c[3];
return 0;
}

همانطور که مشاهده می شود اندیس آرایه بلافاصله بعد از اسم شی می آید .

 


 

سازنده ها (Constructor)

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

برای تعریف کردن تابع costructor به صورت زیر عمل می کنیم.

اسم تابع به نام کلاس می باشد. همچنین می توان به آن پارامتر ورودی تخصیص دهیم. نکته ای که قابل توجه است این است که این تابع نوع خروجی ندارد اما می توان برای آن پارامتر ورودی در نظر بگیریم.

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

class test{
int a;
int b;

public:
test(int n){
a=n;
cout<<"Please Enter b"< cin>>b;
}//end constructor

};

تحلیل مثال: در این مثال کلاسی به اسم test طراحی نموده ایم. که دارای دو فیلد aو b از نوع عدد صحیح می باشد. سپس تابعی سازنده طراحی نموده ایم که یک پارامتر ورودی از کاربر می گیرد و مقدار آن را در a می ریزد سپس در خود تابع مقدار b را به طور مستقیم از کاربر می گیرد. نكته اي جالب اين است كه با اينكه b به صورت private تعريف شده است اما با يك تابع  public مقدار آن را به صورت مستقيم از كاربر گرفته ايم چرا كه تابع مورد استفاده public است. برحال می خواهیم از این کلاس در main یک شی بسازیم:

int main(){
test a(2);
return 0;
}//end programme

وقتی از کلاس test یک شی می سازیم باید مقدار پارامتر ورودی را به تابع سازنده ارائه دهیم که در اینجا مقدار 2 را وارد نموده ایم. سپس در کلاس test در تابع سازنده به دستور cout می رسد و پیغام نوشته شده را چاپ می نماید. بعد از این به دستور cin می رسد و از کاربر به طور مستقیم مقدار b را می خواهد.

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

 


 

مخرب ها (Distructor)

این تابع بعد از اجرا، شی را از بین می برد. به این معنا که دیگر نمی توان از شی استفاده نمود. مثل دستور delete در متغیر های پویا. وقتی شما این تابع را در کلاس خود پیاده سازی نكنيد، این تابع به صورت خودکار در انتهای برنامه اجرا می شود و تنها شی را از بین می برد. شما می توانید این تابع را خودتان پیاده سازی نمایید و به آن امکاناتی اضافه نمایید.

بايد توجه داشت كه در مخرب ها نمي توان به آن پارامتر ورودي تخصيص داد. همچنين مانند سازنده ها مخرب ها نيز مقداري را باز نمي گردانند.

در تعريف مخرب ها مانند آن چه در سازنده ها گفته شد؛ تابع نوع خروجي ندارد. نام تابع به اسم كلاس مي باشد  و قبل از آن از علامت ~ استفاده مي نماييم. به مثال زير توجه كنيد:

class test{
public:
int a;
int b;

~test(){
cout<<"this is distructor"< }//end constructor

};

در اين مثال در كلاس test تابعي تعريف نموده ايم كه به عنوان مخرب به كار رفته و پيغام مورد نظر را چاپ مي كند. در main مي توان از اين تابع استفاده نكرد كه در اين صورت به طور خودكار در انتهاي برنامه اجرا مي شود. از سوي ديگر نيز مي توان اين تابع را به طور مستقيم فراخواني كرد.

int main(){
test a;
a.~test();
return 0;
}//end programme

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

آخرین بروز رسانی مطلب در شنبه ، 25 خرداد 1392 ، 01:49