PDA

View Full Version : آموزش: كلاس ها ، اشيا ، وراثت و چند ريختي (وابسته به تاپیک : ایجاد کتاب پارسی برای دلفی)



SayeyeZohor
چهارشنبه 28 تیر 1391, 22:27 عصر
درود به همه برنامه نویس های گل
در این تاپیک قصد دارم آموزش های در رابطه با برنامه نویسی كلاس ، اشيا ، وراثت و چند ريختي قرار بدم
اين مطالب هم از اطلاعات خودم هست و هم از چند سايت و كتاب
هدف خودنمايي نيست ، هدف من و دوستم آقاي بهروز عباسي فهم بهتر و عميق تر اين مطالب براي خودمون و دوستان برنامه نويس هستش
بيشتر از كتاب جعفرنژاد قمي ، جمع آوري شده
كم كم انشالله تكميلش مي كنم
قبل از توضيح راجع به Thread بهتره اينا رو بدونيم

چند نکته :
1- خواهشاً اگر برای دوستان سوال پیش آمد اول در سایت جستجو کنن بعد اینجا عنوان کنن.
2- به هر حال اگر سوالی پرسیده شد بعد از گرفتن پاسخ و اضافه شدن اون به آموزش اقدام به حذف سوال کنید تا تاپیک در هم بر هم نشه.
3- ممنون مي شم دوستان در مورد نظرات من در صورتي كه ايراد داره نظر بدهند و در صورتي كه نظرشون اعمال شد پستشون رو پاك كنند تا اين تاپيك به هم نريزه شرمنده :خجالت: ممنون

عناوین پست های تاپیک (مرحله به مر حله):
مقدمه (http://barnamenevis.org/showthread.php?351894-%D9%83%D9%84%D8%A7%D8%B3-%D9%87%D8%A7-%D8%8C-%D8%A7%D8%B4%D9%8A%D8%A7-%D8%8C-%D9%88%D8%B1%D8%A7%D8%AB%D8%AA-%D9%88-%DA%86%D9%86%D8%AF-%D8%B1%D9%8A%D8%AE%D8%AA%D9%8A-(%D9%88%D8%A7%D8%A8%D8%B3%D8%AA%D9%87-%D8%A8%D9%87-%D8%AA%D8%A7%D9%BE%DB%8C%DA%A9-%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF-%DA%A9%D8%AA%D8%A7%D8%A8-%D9%BE%D8%A7%D8%B1%D8%B3%DB%8C-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%AF%D9%84%D9%81%DB%8C)&p=1552209&viewfull=1#post1552209)

كلاس ها در دلفي (http://barnamenevis.org/showthread.php?351894-%D9%83%D9%84%D8%A7%D8%B3-%D9%87%D8%A7-%D8%8C-%D8%A7%D8%B4%D9%8A%D8%A7-%D8%8C-%D9%88%D8%B1%D8%A7%D8%AB%D8%AA-%D9%88-%DA%86%D9%86%D8%AF-%D8%B1%D9%8A%D8%AE%D8%AA%D9%8A-(%D9%88%D8%A7%D8%A8%D8%B3%D8%AA%D9%87-%D8%A8%D9%87-%D8%AA%D8%A7%D9%BE%DB%8C%DA%A9-%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF-%DA%A9%D8%AA%D8%A7%D8%A8-%D9%BE%D8%A7%D8%B1%D8%B3%DB%8C-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%AF%D9%84%D9%81%DB%8C)&p=1552223&viewfull=1#post1552223)

ساختار كلاس (http://barnamenevis.org/showthread.php?351894-%D9%83%D9%84%D8%A7%D8%B3-%D9%87%D8%A7-%D8%8C-%D8%A7%D8%B4%D9%8A%D8%A7-%D8%8C-%D9%88%D8%B1%D8%A7%D8%AB%D8%AA-%D9%88-%DA%86%D9%86%D8%AF-%D8%B1%D9%8A%D8%AE%D8%AA%D9%8A-(%D9%88%D8%A7%D8%A8%D8%B3%D8%AA%D9%87-%D8%A8%D9%87-%D8%AA%D8%A7%D9%BE%DB%8C%DA%A9-%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF-%DA%A9%D8%AA%D8%A7%D8%A8-%D9%BE%D8%A7%D8%B1%D8%B3%DB%8C-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%AF%D9%84%D9%81%DB%8C)&p=1552236&viewfull=1#post1552236)

مثال از يك كلاس (http://barnamenevis.org/showthread.php?351894-%D9%83%D9%84%D8%A7%D8%B3-%D9%87%D8%A7-%D8%8C-%D8%A7%D8%B4%D9%8A%D8%A7-%D8%8C-%D9%88%D8%B1%D8%A7%D8%AB%D8%AA-%D9%88-%DA%86%D9%86%D8%AF-%D8%B1%D9%8A%D8%AE%D8%AA%D9%8A-(%D9%88%D8%A7%D8%A8%D8%B3%D8%AA%D9%87-%D8%A8%D9%87-%D8%AA%D8%A7%D9%BE%DB%8C%DA%A9-%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF-%DA%A9%D8%AA%D8%A7%D8%A8-%D9%BE%D8%A7%D8%B1%D8%B3%DB%8C-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%AF%D9%84%D9%81%DB%8C)&p=1552282&viewfull=1#post1552282)

متد سازنده كلاس (Constructor) (http://barnamenevis.org/showthread.php?351894-%D9%83%D9%84%D8%A7%D8%B3-%D9%87%D8%A7-%D8%8C-%D8%A7%D8%B4%D9%8A%D8%A7-%D8%8C-%D9%88%D8%B1%D8%A7%D8%AB%D8%AA-%D9%88-%DA%86%D9%86%D8%AF-%D8%B1%D9%8A%D8%AE%D8%AA%D9%8A-(%D9%88%D8%A7%D8%A8%D8%B3%D8%AA%D9%87-%D8%A8%D9%87-%D8%AA%D8%A7%D9%BE%DB%8C%DA%A9-%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF-%DA%A9%D8%AA%D8%A7%D8%A8-%D9%BE%D8%A7%D8%B1%D8%B3%DB%8C-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%AF%D9%84%D9%81%DB%8C)&p=1552312&viewfull=1#post1552312)

نمونه سازي از كلاس (http://barnamenevis.org/showthread.php?351894-%D9%83%D9%84%D8%A7%D8%B3-%D9%87%D8%A7-%D8%8C-%D8%A7%D8%B4%D9%8A%D8%A7-%D8%8C-%D9%88%D8%B1%D8%A7%D8%AB%D8%AA-%D9%88-%DA%86%D9%86%D8%AF-%D8%B1%D9%8A%D8%AE%D8%AA%D9%8A-(%D9%88%D8%A7%D8%A8%D8%B3%D8%AA%D9%87-%D8%A8%D9%87-%D8%AA%D8%A7%D9%BE%DB%8C%DA%A9-%D8%A7%DB%8C%D8%AC%D8%A7%D8%AF-%DA%A9%D8%AA%D8%A7%D8%A8-%D9%BE%D8%A7%D8%B1%D8%B3%DB%8C-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%AF%D9%84%D9%81%DB%8C)&p=1552313&viewfull=1#post1552313)


موفق باشید
این مطلب ادامه دارد

SayeyeZohor
پنج شنبه 29 تیر 1391, 17:43 عصر
مقدمه
كلاس چيست ؟
كلاس نوع جديدي است كه براي مدل سازي اشياي دنياي واقعي مورد استفاده قرار مي گيرد ، هر يك از اشياي دنياي واقعي داراي خواص و رفتارهايي هستند .
کلاس ها دقیقا مثل اشیا و وسایل در دنیای واقعی هستند .

مثال 1 :
يك توپ داراي اين خواص است : وزن ، رنگ و اندازه . (خواص اشياي دنياي واقعي به عنوان اعضاي داده اي كلاس هستند)
توپ رفتارهايي از خود نشان مي دهد مانند پرباد بودن و غلتيدن و پنچر شدن (رفتارهاي اشياي دنياي واقعي به عنوان متد هاي كلاس هستند) . متد هاي كلاس را مي توان به صورت تابع (Function) يا رويه (Procedure) نوشت .
در زبان های برنامه نویسی قدیمی مثل پاسکال و سی (C) شما با تعداد زیادی تابع و دستور سروکار داشتید و بسته به نیاز خود از هر کدام استفاده می کردید ولی در زبان های جدید تر مثل سی پلاس پلاس (C++‎‎‎‎‎‎‎‎‎) و وی بی دات نت (VB.NET) یا دلفي (Delphi) شما با مفهوم جدیدی به نام کلاس مواجه می شوید .

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

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

خوب حالا کلاس ها چه استفاده ای دارند؟
فرض کنید ما یک برنامه داریم که شامل چندین صفحه و بیش از هزار خط كد باشد و در این برنامه یک کد پنجاه خطی برای انجام یک وظیفه ,در بخشهای مختلف برنامه چندین بار نوشته و استفاده شده است
حالا بعد از مدتی به یک باگ در این کد پی میبریم یا اینکه بخواهیم یک تغيیری در روش کارش انجام بدیم چاره چیست؟
باید تک تک جاهايی که این کد استفاده شده روپیدا کنیم و تغیير بدهیم که کلی زمان و کار از ما خواهد گرفت.
ولی در صورتی که این کد رو بصورت کلاس یا همان شی استفاده کرده باشیم نیازی به این همه زحمت نخواهد بود و با تغبیر کلاس تمام نمونه ها یا اشیا ساخته شده از اون کلاس تغيیر می کنند.
تازه این فقط یکی از مزایای کلاس ها است به غیر از این میتوان به ارث بری کلاسها , توسعه آسان برنامه, کم کردن حجم برنامه, خوانایی بالای برنامه و … اشاره نمود .

SayeyeZohor
پنج شنبه 29 تیر 1391, 18:04 عصر
كلاس ها در دلفي
در برنامه نويسي شي گرا سه مفهوم اصلي بسته بندي (Encapsulation) ، وراثت (Inheritance) و چند ريختي (Polymorphism) وجود دارد .
1- بسته بندي : فيلد هاي داده اي مرتبط به هم را تركيب كرده و جزئيات پياده سازي را مخفي مي كنيم .
2- وراثت : مي توان اشياء جديدي از اشيا موجود ايجاد كرد كه همان خواص اشياي موجود را داشته باشد . (شيء جديد را شيء مشتق (شيء فرزند) و شيء موجود را شيء پدر مي گويند .
امتياز وراثت اين است كه از كدهاي مشترك استفاده مي شود .

http://barnamenevis.org/attachment.php?attachmentid=89941

3- چند ريختي

نوشتن متد ها در دومرحله صورت مي گيرد :
مرحله اول – متد ها را در داخل كلاس اعلان مي كنيم
مرحله دوم – متدها را تعريف مي كنيم
هنگام تعريف متد (نوشتن بدنه متد) ، بايد مشخص كنيد كه آن متد مربوط به كدام كلاس است .

SayeyeZohor
پنج شنبه 29 تیر 1391, 18:22 عصر
ساختار كلاس
اعضاي كلاس شامل داده ها (فيلدها) و متدها هستند .
كلاس ها مي توانند چهار سطح دسترسي دارند
1 – سطح اختصاصي (Private) : اعضاي موجود در اين بخش از كلاس ، توسط متدهايي كه عضو كلاس هستند قابل دستيابي است ، بنابراين كاربران نمي توانند به طور مستقيم به اين اعضا دسترسي داشته باشند.
2 – سطح ... (Strict Private) :
3 – سطح عمومي (Public) : اعضايي كه در اين بخش از كلاس قرار دارند در هر جايي از برنامه قابل دستيابي هستند .
4 – سطح محافظت شده (Protected) : اعضايي كه در اين بخش از كلاس قرار دارند توسط كلاس هاي مشتق شده (كلاس هاي فرزند) قابل دستيابي هستند .
5 – سطح ... (Strict Protected) :
6 – سطح منتشر شده (Published) :‌ سطح دسترسی published عملکردی مشابه public داره با این تفاوت که اگر کلاس مربوطه کامپوننت باشه و در IDE دلفی نصب شده باشه، خصوصیات لیست شده در بخش published در زمان طراحی در داخل Object Inspector نمایش داده میشند، و کاربر میتونه به صورت بصری مقادیر آنها را تغییر بده. به عبارت فنی تر، کامپایلر برای خصوصیات لیست شده در بخش published به طور خودکار RTTI تولید میکنه که مورد استفاده IDE قرار میگیره.
(كمك آقاي علی کشاورز (http://barnamenevis.org/member.php?4729-%D8%B9%D9%84%DB%8C-%DA%A9%D8%B4%D8%A7%D9%88%D8%B1%D8%B2))

ساختار كلي كلاس

type
نام كلاس = class
private
{ Private declarations }
اعضاي اختصاصي
strict private
{strict private declarations }
...
public
{ Public declarations }
اعضاي عمومي
protected
{ protected declarations }
اعضاي محافظت شده
strict protected
{strict protected declarations }
...
published
{ published declarations }
اعضاي منتشر شده
end;

SayeyeZohor
پنج شنبه 29 تیر 1391, 19:18 عصر
مثال از يك كلاس :


interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;

type
Test = class
private
{ Private declarations }
Width: Integer; {عرض مستطيل}
Length: Integer; {طول مستطيل}
Area: Integer; {عرض مساحت}
Perime: Integer; {محيط مستطيل}
public
{ Public declarations }
procedure Input;
procedure Calculate;
procedure Output;
constructor Create;
destructor Destroy; override;
protected
{ protected declarations }
published
{ published declarations }
end;


implementation

{$R *.dfm}

procedure Test.Input;
begin
Width := StrToInt(InputBox('InputBox', 'Width', ''));
Length := StrToInt(InputBox('InputBox', 'Length', ''));
end;

procedure Test.Calculate;
begin
Perime := (Width + Length) * 2;
Area := (Width * Length);
end;

procedure Test.Output;
begin
ShowMessage('Area = ' + IntToStr(Area) + 'Perime = ' + IntToStr(Perime));
end;

constructor Test.Create;
begin

end;

destructor Test.Destroy;
begin
inherited;
end;


نحوه استفاده از اين كلاس در برنامه هاي خودمون :


procedure TForm1.Button1Click(Sender: TObject);
var
t1: Test;
begin
t1 := Test.Create;
t1.Input;
t1.Calculate;
t1.Output;
FreeAndNil(t1);
end;



در اين كلاس ،
4 عضو داده اي به نام هاي ‌Width , Length , Area و Perime
3 متد به نام هاي Input (براي خواندن طول و عرض) ، Calculate (براي محاسبه مساحت و محيط مستطيل) و Output (براي چاپ مساحت و محيط مستطيل) است .
براي نوشتن متد هاي كلاس ، بايد نام كلاس همراه با نام متد ذكر شود .
اين متدها در بخش implementation نوشته مي شوند و تعريف كلاس هم در قسمت interface صورت مي گيرد .

SayeyeZohor
پنج شنبه 29 تیر 1391, 19:51 عصر
متد سازنده كلاس (Constructor) :
اين متد براي مقدار اوليه دادن به اعضاي كلاس و اخذ حافظه براي نمونه هايي از كلاس به كار مي رود .

مثال :


type
Test1 = class
private
{ Private declarations }
a: Integer;
b: Integer;
public
{ Public declarations }
procedure Print;
constructor Create;
destructor Destroy; override;
protected
{ protected declarations }
published
{ published declarations }
end;

implementation

{$R *.dfm}

procedure Test1.Print;
begin
ShowMessage('a = ' + IntToStr(a) + ', b = ' + IntToStr(b));
end;

constructor Test1.Create;
begin
a := 10;
b := 20;
end;

destructor Test1.Destroy;
begin
inherited;
end;


اين كلاس داراي دو عضو داده اي a , b و يك زير برنامه (متد - پروسيجر) به نام Print و يك تابع سازنده به نام Create است .
تابع سازنده به a , b مقدار اوليه 10 و 20 را مي دهد و پروسيجر Print آن ها رو چاپ مي كند .

SayeyeZohor
پنج شنبه 29 تیر 1391, 19:51 عصر
نمونه سازي از كلاس :

وقني كلاسي ايجاد شد بايد نمونه اي از آن كلاس تعريف شود تا بتوان از آن استفاده كرد .


var
t1, t2: Test1;


در دستور بالا ، t1 , t2 دو نمونه از كلاس Test1 تعريف شده اند.
اما اين تعريف كافي (اعلان) نيست ، بلكه بايد براي هر نمونه ، حافظه اي اختصاص داد.
براي تخصيص حافظه به نمونه هاي آن كلاس از سازنده ها استفاده مي گردد.

من خودم با اين خط پايين يك مشكلي دارم :
بنابراين هر كلاسي بايد حداقل يك سازنده داشته باشد تا بتواند نمونه هاي آن كلاس را ايجاد نمايد .
مشكل من : چرا حتماً بايستي به اين ها حافظه اختصاص داده بشه
(چرا هر كلاسي بايد حداقل يك سازنده داشته باشد ؟)
جواب از آقاي علی کشاورز (http://barnamenevis.org/member.php?4729-%D8%B9%D9%84%DB%8C-%DA%A9%D8%B4%D8%A7%D9%88%D8%B1%D8%B2) :


کلاس یک ساختار داده دینامیک هست که برخلاف داده های ساده (مثل عدد صحیح) که در stack ذخیره میشند، بر روی حافظه heap ایجاد میشه. وجود متد سازنده برای یک کلاس لازم هست تا:
1- حافظه مورد نیاز برای داده های موجود در یک کلاس به آن اختصاص داده شود.
2- به فیلدهای کلید مقادیر اولیه اختصاص داده شود، و برنامه نویس امکان اجرای عملیات لازم برای آماده سازی اولیه کلاس خود را داشته باشد.


مثال :


var
t1, t2: Test1;
begin
t1 := Test1.Create;
t2 := Test1.Create;

FreeAndNil(t1);
FreeAndNil(t2);
end;



در مثال بالا
- با دستور var t1, t2: Test1; دو نمونه به نام هاي t1 , t2 تعريف شده

- با اين دو دستور كه در اين كتاب از آن چيزي نگفته ، اين دو نمونه از نوع كلاس Test1 ايجاد مي شوند (حافظه به آن ها اختصاص مي يابد).

t1 := Test1.Create;
t2 := Test1.Create;


- با اين دستور حافظه اختصاص يافته را آزاد مي كنيم

FreeAndNil(t1);
FreeAndNil(t2);


(ممنون مي شم دوستان در مورد نظرات من در صورتي كه ايراد داره نظر بدهند و در صورتي كه نظرشون اعمال شد پستشون رو پاك كنند تا اين تاپيك به هم نريزه شرمنده :خجالت:)

vcldeveloper
پنج شنبه 29 تیر 1391, 20:30 عصر
كلاس ها مي توانند چهار سطح دسترسي دارند
شش سطح دسترسی:
strict private
private
strict protected
protected
public
published



سطح منتشر شده (Published) :‌ همانند سطح عمومي است با اين تفاوت كه فقط در زمان اجرا قابل دسترسي مي باشند ، بنا براين اگر خاصيتي را در دسترسي همگاني قرار داده باشيد ،كاربران مولفه شما مي توانند آن را در زمان اجرا تنظيم يــا بازرسي كنند،ولي چنيــن اختياري را در زمان طـراحي ندارند . (از حدسيات خودم مي باشد)
سطح دسترسی published عملکردی مشابه public داره با این تفاوت که اگر کلاس مربوطه کامپوننت باشه و در IDE دلفی نصب شده باشه، خصوصیات لیست شده در بخش published در زمان طراحی در داخل Object Inspector نمایش داده میشند، و کاربر میتونه به صورت بصری مقادیر آنها را تغییر بده. به عبارت فنی تر، کامپایلر برای خصوصیات لیست شده در بخش published به طور خودکار RTTI تولید میکنه که مورد استفاده IDE قرار میگیره.

vcldeveloper
پنج شنبه 29 تیر 1391, 20:34 عصر
من خودم با اين خط پايين يك مشكلي دارم :
بنابراين هر كلاسي بايد حداقل يك سازنده داشته باشد تا بتواند نمونه هاي آن كلاس را ايجاد نمايد .
مشكل من : چرا حتماً بايستي به اين ها حافظه اختصاص داده بشه (چرا هر كلاسي بايد حداقل يك سازنده داشته باشد ؟)
کلاس یک ساختار داده دینامیک هست که برخلاف داده های ساده (مثل عدد صحیح) که در stack ذخیره میشند، بر روی حافظه heap ایجاد میشه. وجود متد سازنده برای یک کلاس لازم هست تا:
1- حافظه مورد نیاز برای داده های موجود در یک کلاس به آن اختصاص داده شود.
2- به فیلدهای کلید مقادیر اولیه اختصاص داده شود، و برنامه نویس امکان اجرای عملیات لازم برای آماده سازی اولیه کلاس خود را داشته باشد.

SayeyeZohor
جمعه 30 تیر 1391, 12:19 عصر
متد مخرب كلاس : (Destructor)

تابع سازنده مي تواند نمونه هايي از كلاس را ايجاد نمايد . تابع مخرب وقتي فراخواني مي شود كه نمونه اي از كلاس از بين مي رود . هر كلاس مي تواند چند مخرب داشته باشد ، ولي اگر يك مخرب داشته باشد ، نامش بايد Destroy باشد .