PDA

View Full Version : مهفوم overide در دلفي و پياده سازي آن



shervin farzin
پنج شنبه 03 مرداد 1387, 17:30 عصر
با سلام
ميخواستم در مورد كلمه كليدي override اطلاعاتي داشته باشم .
اگه بتونين يه مثال هم همراهش به من بگين كه ديگه كلي دعاتون ميكنم :تشویق:

Hsimple11
پنج شنبه 03 مرداد 1387, 20:01 عصر
این لینک (http://barnamenevis.org/forum/%D9%85%D8%A8%D8%A7%D8%AD%D8%AB-%D9%85%D8%B1%D8%A8%D9%88%D8%B7-%D8%A8%D9%87-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D8%AF%D8%B1-delphi/44389-%D8%A7%D9%86%D8%AF%D8%B1-%D8%A7%D8%AD%D9%88%D8%A7%D9%84%D8%A7%D8%AA-virtual-%D9%88-override.html) رو ببینید.

بطور کلی Override متدی را مشخص می کند که جایگزین متدی با همان نام می شود که در کلاس والد(Parent) وجود دارد :


Function|Procedure declaration; Override;

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

مثالهای آن در سایت موجود است.

دوستان دیگر اگر توضیحات جامع تری در این مورد بدهند من هم ممنون میشوم.

shervin farzin
پنج شنبه 03 مرداد 1387, 20:41 عصر
ممنون از جوابت . من با overload آشنام و تعريفي كه شما ارائه فرمودين خيلي
شبيه overload ميشه . اگه ميشه فرق overload و override رو هم بي زحمت بفرماييد .
ممنونم .

Hsimple11
پنج شنبه 03 مرداد 1387, 21:18 عصر
متاسفانه من در مورد overload کار نکردم و اطلاعاتی ندارم. پس این تاپیک را پیگیری میکنم و حتما نظر دیگران را همراه با شما میخوانم :)

موفق باشید...

B-Vedadian
پنج شنبه 03 مرداد 1387, 23:38 عصر
overload به override هيچ ربطي نداره.

وقتي يک کلاس رو از يک کلاس ديگه ارث ببري، تمام توابع مجازي اون هم به ارث برده ميشه. حالا اگه بخواي بعضي از اون‏ها تو کلاس فرزند کار ديگه‏اي بکنند، اين کار رو بهش ميگن override کردن.

مثال: يک کلاس کلي به نام حيوان ايجاد کرديم که مثلا يک تابع مجازي به نام صدا داره. حالا دو تا کلاس ديگه مثلا مرغ و گاو رو از اون مشتق ميکنيم. حالا در مورد اين دو تا کلاس تابع صدا، کارهاي متفاوتي ميکنه، براي مرغ صداي "قدقد" و براي گاو صداي "ماو" رو داريم.

حالا اين به چه درد ميخوره؟ کاربردش تو برنامه نويسي چند ريختيه. مثلا يک برنامه نوشتيد، مزرعه. چند تا حيون رو شبيه سازي کرديد، برنامه اصلي براي هر کدوم از حيون‏ها تابع صدا رو فراخواني ميکنه ولي حيوونا بسته به اينکه چي هستن عکس العمل‏هاي متفاوتي رو نشون ميدن.

يک مثال ديگه. فرض کن يک تابع مرتب‏سازي نوشتي، ورودي بهش يک کلاس کلي مثلا به اسم "مرتب شونده" هست. اين ميتونه يک عدد (حقيقي يا صحيح) يا ماتريس باشه. تابع مرتب‏ساز تو نمي‏خواد با ماهيت اين پارامتراش سر و کار داشته باشه، فقط از عملگرهاي بزرگتر و کوچکتر استفاده ميکنه. تو اين موارد چند ريختي کمک ميکنه، شما يک برنامه براي کلاس کلي مينويسي، بسته به اينکه چه نوع پارامتري بهش بدي، توابع override شده مربوطه صدا زده ميشن.

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

دقت بشه که در مثال مرتب‏سازي، چند تا تابع مرتب‏سازي متفاوت براي انواع داده متفاوت وجود نداره. همون يک تابع هست و فقط عملگرهاي کوچکتر و بزرگتر بسته به نوع عوض ميشن ...

shervin farzin
پنج شنبه 03 مرداد 1387, 23:51 عصر
سلام
ممنونم از جوابت . اگه ميشه يه كد به عنوان مثال بنويس تا خوب شير فهم بشم .

SYNDROME
جمعه 04 مرداد 1387, 08:50 صبح
سلام
ممنونم از جوابت . اگه ميشه يه كد به عنوان مثال بنويس تا خوب شير فهم بشم .
برای مفهوم OverLoad می توان چنین مثالی زد.
چهار تابه زیر را توجه کنید که نامهای یکسان دارند.


Function SYNDROME(Name : string):String;Overload;
Function SYNDROME(Name,Family : string):String;Overload;
Function SYNDROME(Name : Bollean):String;Overload;
Function SYNDROME(Name,Family : Bollean):String;Overload;

حالا اگر شما تابع را به شکل زیر فراخوانی کنید


SYNNDROME('Ahmad');

تابع اولی فراخوانی می شود.
اگر اینچنین فراخوانی کنید


SYNNDROME('Ahmad','Ahmady');

تابع دوم فراخوانی می شود.
اگر اینچنین فراخوانی کنید


SYNNDROME(True);

تابع سوم
اگر اینچنین فراخوانی کنید


SYNNDROME(True,True);

تابع چهارم فراخوانی می شود.
با توجه به تعداد پارامترهای ورودی و یا نوع آنها می توان چنین عملی انجام دارد.
موفق باشید

shervin farzin
شنبه 05 مرداد 1387, 12:33 عصر
آقا ممنون از جوابت ولي من با Overload آشنا هستم . اگه ميشه يه مثال از Override
بنويسيد لطفا .

B-Vedadian
شنبه 05 مرداد 1387, 18:50 عصر
لازم به مثال نيست. يک پروژه تو دلفي درست کن و برو توش رو Classes کنترل کليک کن.

shervin farzin
سه شنبه 08 مرداد 1387, 12:43 عصر
سلام

آقا يه سوال . من ميتونم از كلمه override براي ارث بري از يك متد virtual در يك كلاس ديگه استفاده كنم . سوالم اينه كه اگه جلوي اعلان تابع پدر ننويسم virtual و جلوي اعلان تابع فرزند هم ننويسم override هيچ تفاوتي چه در گرامر و چه در منطق برنامه به وجود نمياد !!!!
مي خواستم بدونم چه جاهايي مجبور ميشم تا از اين دو كلمه كليدي براي نمايش ارث بري حتما استفاده كنم ؟
ممنون

B-Vedadian
سه شنبه 08 مرداد 1387, 14:05 عصر
چطور پیش نمیآد! کلا میشه یه چیز دیگه.

این‏ها همه موقع casting خودشو نشون میده. وقتی virtual تعریف نکنید و به عنوان کلاس والد از شئی که از نوع کلاس فرزند هست، استفاده کنید، متد والد صدا زده میشه در حالی که اگه virtual بود در هر حالت متد فرزند صدا زده میشد.

shervin farzin
سه شنبه 08 مرداد 1387, 15:13 عصر
به اين مثال نگاه كنيد ..


type
TFurniture = class (TObject)
public
function GetKind: string;virtual;
end;

TChair = class (TFurniture)
public
function GetKind: string;override;
end;
{.........}‍‌
implementation

{$R *.dfm}

procedure call(x: TFurniture);
begin
showmessage(x.GetKind);
end;

{ TFurniture }

function TFurniture.GetKind: string;
begin
Result := 'Furniture';
end;

{ TChair }

function TChair.GetKind: string;
begin
Result := 'A Chair';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
x:TFurniture;
y:TChair;
begin
x:=TFurniture.Create;
y:=TChair.Create;
call(x);
call(y);
end;

اين مثال رو وقتي اجراء ميكنم Error ميده ( يه Error خواندن از حافظه ) اما وقتي كلمات Override , virtual رو ازش حذف ميكنم بدون Error فقط عبارت Furniture رو نمايش ميده ( همون موردي كه شما فرموديد ) . اشكال كارم كجاست ؟

B-Vedadian
سه شنبه 08 مرداد 1387, 17:13 عصر
من عین کد شما رو اجرا کردم، بدون خطا!