آموزش پاسکال شی‌گرا

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 هستند
اشاره به این نکته ضروری است که درمثال قبلی اقدام به آزاد کردن حافظه مربوط به نمونه‌ها نکردیه‌ایم
لذا حافظه مربوطه بلااستفاده خواهد ماند

در پست های بعدی در این مورد بحث خواهیم کرد

[adinserter block="1"]
5/5 - (3 امتیاز)

نوشته های مشابه

دیدگاهتان را بنویسید

دکمه بازگشت به بالا