Constructor ها در پاسکال شیگرا

Constructor ها در پاسکال شیگرا
به متدی که باعث ایجاد یک نمونه جدید از کلاس میگردد Constructor گفته میشود
Constructor در لغت به معنای سازنده است و در عمل نیز برای همین منظور استفاده میشود
تعجب کرده اید ؟! اگر با رکوردها کار کرده باشید نباید تعجب کنید
همان طور که تعریف یک رکورد باعث ایجاد یک نمونه از ان در حافظه نمیشود
در مورد کلاس نیز این موضوع صادق است
برای درک بهتر به تعریف رکورد زیر توجه کنید
type TSudent = record Name : string[20]; Family : string[30]; end;
حال با تعریف کلاس زیر توجه کنید
type TCar = class private started : Boolean; Speed : Byte; Procedure StartEngine; Procedure StopEngine; Public Procedure Start; Procedure ShutDown; function GetSpeed : Byte; end;
توجه داشته باشید مواردی که در قسمت Type معرفی میشوند
باعث تخصیص حافظه نخواهد شد
لذا با توجه به این که رکورد و کلاس در قسمت Type معرفی می شوند
حافظه ای به آن ها تخصیص داده نمیشود
نکــــــــته |
---|
به طور خلاصه این که تعریف یک کلاس مشابه با ایجاد یک قالب است که میتوانید توسط این قالب نمونه هایی متعددی را به وجود آورید در برنامه نویسی شیگرا معمولا به قالب کلاس اطلاق میکنند و به نمونه هایی که ازقالب ساخته میشوند نمونه یا شی میگویند |
ایجاد نمونه ای ازیک کلاس نیاز به حافظه دارد
وظیفه متد Constructor این است که حافظه مورد نیاز کلاس را تخصیص داده متغییرهای مربوط به کلاس را مقداردهی اولیه میکند و یا هر وظیفه دیگری را که برای شروع به کار مورد نیاز شد انجام میدهد
در مثال قبلی ما فاقد Constructor بود
در صورتی که یک کلاس فاقد Constructor باشد شما میتوانید از متد Constructor مربوط به جد اصلی کلاس استفاده کنید
تعجب کرده اید ؟! باید بدانید که در پاسکال شیگرا تمامیکلاس ها از TObject منشعب میشوند
و در حقیقت TObject یک کلاس است و متدهای اساسی مثل ساختن و تخریب اشیا را شامل میشود
و جد اصلی تمامی کلاس هاست
کلاس TObject شامل یک Constructor با نام Create است
لذا در صورتی که یک کلاس فاقد Constructor باشد
میتواند از متد Create استفاده کند
توجه داشته باشید که در رابطه با وراثت در ادامه توضیحات کاملی ارایه خواهد شد
لازم به ذکر است که در مورد کلاس های ساده استفاده از Constructor مربوط به جد اصلی کلاس روش معقولانهای است
شمامی توایند Constructor ویژه خود را به وجود آورده و نام آن را نیز به دلخواه تعیین کنید
اما برای تعریف آن باید از کلمه کلیدی Constructor استفاده کنید
برای مثال در تعریف کلاس بعد از Constructor نیز استفاده شده است
type TCar = class Private Started : Boolean; Speed : Byte; procedure StartEngine; procedure StopEngine; public procedure Start; procedure ShutDown; function GetSpeed : Byte; constructor Create; end;
توجه داشته باشید که Constructor متد ویژهای است که میتواند دارای نوع بازگشتی باشد
چرا ؟ برای این که Constructor نمیتواند مقدار دهی را بازگرداند
در صورتی که شما درتعریف Constructor از نوع بازگشتی استفاده کنید کامپایلر ازشما ایراد خواهد گرفت
یک کلاس میتواند شامل بیش ازیک Constructor باشد
این امر از دو طریق مسیر است
روش اول این است که هر Constructor از نام متفاوتی استفاده کند.
type TCar = class Private Started : Boolean; Speed : Byte; procedure StartEngine; procedure StopEngine; public procedure Start; procedure ShutDown; function GetSpeed : Byte; constructor Create; constructor CreateModel(Model : string); end;
روش دوم این است که با استفاده از تکنیک Method Overloading این کار را انجام دهید
در رابطه با Method Overloading در پست های اینده توضیحات کاملی ارایه داده خواهد شد
برای مثال در تعریف زیر از دو Constructor با اسامی یکسان استفاده شده است
type TCar = class Private Started : Boolean; Speed : Byte; procedure StartEngine; procedure StopEngine; public procedure Start; procedure ShutDown; function GetSpeed : Byte; constructor Create;Overload; constructor Create(Model : Sttring); overload; end;
شاید این پرسش به ذهن شما خطور کرده باشد
که داشتن چند Constructor چه مزیتی دارد ؟
پاسخ این است که با استفاده از چندین Constructor میتوانید با روش های مختلفی یک کلاس را به وجود اورید
برای مثال یک کلاس میتواند شامل دو Constructor باشد که یکی فاقد پارامتر و دیگری دارای پارامتر باشد
و با استفاده از پارامترها اقدام به مقدار دهی اولیه فیلدها کند
برای مثال این کلاس را در نظر بگیرد
type TMyRect = class Private Left : Integer; Top : Integer; Right : Integer; Bottom : Integer; public function GetWidth : Integer; function GetHeight : Integer; procedure SetRect (Aleft, Atop, Aright, Abottom : Integer); end;
همان طور که مشاهده میکنید کلاس فوق برای ترسیم مستطیل به وجود آمده است
و شامل دو Constructor است
فرض کنید پیاده سازی اولین Constructor آن به صورت زیر باشد
constructor TMyRect.Create; begin inherited Creat; Left := 0; Top := 0; Right := 0; Bottom := 0; end;
پیادسازی Constructor آن به این صورت باشد
Constructor TmyRect.CreateVal(ALeft,Atop,ARight,ABottom: integer); begin integerited Create; Left : ALeft; Top : ATop; Right : ARight; Bottom : ABottom; end;
اولین Constructor به سادگی تمامی فیلدها را با صفر مقداردهی میکند
اما دومینConstructor فیلدهای کلاس را با توجه به پارامترهای ارسال شده مقداردهی میکند
توجه داشته باشید که متغییرهای درون لیست پارامترها برای Constructor حکم متغییرهای محلی را دارند
و در دلفی مرسوم است که اسامی متغییرهای پارامتر ها را با پیشوند A مشخص میکنند
حتما ازدیدن کلمه کلیدی integerited کمی جا خورده اید
زیاد تعجب نکنید زیرا در رابطه با وراثت و کلمه کلیدی integerited در ادامه به طور کامل شرح خواهم داد
نکــــــته |
---|
توجه داشته باشید که لزومی ندارد مقداردهی اولیه فیلدها با مقدار صفر باشد زیرا وقتی نمونه ای از یک کلاس ایجاد میشود تمامی فیلدها به صورت خودکار با مقدار صفر مقداردهی میشوند |
حتما خسته شده اید و میخواهید سریع تر بدانید که چگونه میتوانید
نمونه ای از یک کلاس را به وجود آوردید؟
من هم مثل شما عجله دارم که اصل موضوع را مطرح کنم
لذا به کد زیر توجه کنید
var Rect1 : TMyRect; Rect2 : TMyRect; begin Rect1 : TMyRect.Create; Rect2 : TMyRect.CreateVal(0, 0, 100, 100); end;
کد فوق باعث ایجاد دو نمونه ( یا به طور عامیانه دو شی ) از کلاس TMyRect خواهد شد
اولین عبارت درون بلوک کد فوق از Create و دومین CreateVal استفاده کرده است
توجه داشته باشید که هر دو نمونه از تخصیص حافظه پویا استفاده کردهاند
حتما با توجه به مطالب قبلی وب سایت سوال خواهید کرد
که در این عبارات از تابع AllocMem خبری نیست
پس چگونه به صورت پویا از خافظه استفاده شده است؟!
پاسخ این است که در زبان پاسکال شیگرا حافظه مربوط به کلاس ها همیشه به صورت پویا تخصیص می یابد
ودر مثال قبلی متغییر های Rect1 و Rect2 اشاره گرهایی به کلاس TMyRect هستند
اشاره به این نکته ضروری است که درمثال قبلی اقدام به آزاد کردن حافظه مربوط به نمونهها نکردیهایم
لذا حافظه مربوطه بلااستفاده خواهد ماند
در پست های بعدی در این مورد بحث خواهیم کرد