السلام عليكم ورحمة الله تعالى وبركاته
نعلم أن classe méthodes تكون إما virtual او static لكن لم افهم الفرق بينهم ومتى أستعمل كل وحدة.
قمت بإنشاء class على النحو التالي :
كود :
unit uClassA;
interface
type
TClassA = class(TObject)
public
class function Add(pA,pB: integer): integer;
end;
implementation
{ TClassA }
class function TClassA.Add(pA, pB: integer): integer;
begin
Result:= (pA + pB);
end;
end.
يوجد 3 حالات لتعريف method :
1- بدون ايي كلمة مفتاحية (لا static لا virtual)
كود :
class function Add(pA,pB: integer): integer;
2-
[size=small]بإستخدام [/size]static
كود :
class function Add(pA,pB: integer): integer; static;
3- بإستخدام virtual
كود :
class function Add(pA,pB: integer): integer; virtual;
الكل يشتغلون بدون مشاكل عبر هذا الكود (لا يوجد فرق في النتيجة)
كود :
ShowMessage(TClassA.Add(10,20).toString);
اين هو الفرق إذا ؟
كل class method هي static بشكل افتراضي.
خاصية virtual توضع وراء أية method أو إجراء في كلاس ما إذا اردت من الكلاسات المنحدرة منها اعادة تعريف الاجراء, وليس شرط أن تكون class function أو class procedure.
مثلا في كلاس عادية:
PHP كود :
type
TVehicle = class
public
procedure Move; virtual;
end;
بعدها كلاس أخرى ترثها وتعيد تعريف الاجراء Move بما يناسبها هي:
PHP كود :
type
TCar = class(TVehicle)
public
procedure Move; override;
end;
في حالة كانت class function أو class procedure بغض النظر ان كانت virtual أو لا, يمكن استخدامها بدون انشاء object لذلك الكلاس, ففي مثالك لم تنشئ object أو instance للكلاس TClassA واستخدمت الاجراء مباشرة بعد ذكر اسم الكلاس.
مثالي ليس مناسب, لكن اتمنى ان تصل الفكرة.
الله ينورك أخي سفيان
- نستعمل virtual لنقول أن هذه الـ method يمكن أن نعمل لها override في الكلاسات المشتقة(childe class).
- override تعني تغيير السلوك (التعليمات) الموجودة في الـ method الخاصة بالكلاس الأصلية (parent class).
إذا كان هذا صحيح, يمكن فعل نفس الشيء بدون إستخدام virtual و override
وهذا كود توضيحي :
كود :
unit uClassA;
interface
uses Vcl.Dialogs;
type
TClassA = class(TObject)
public
procedure GetInfo;
end;
TClassB = class(TClassA)
public
procedure GetInfo;
end;
implementation
{ TClassA }
procedure TClassA.GetInfo;
begin
ShowMessage('ClassA.GetInfo');
end;
{ TClassB }
procedure TClassB.GetInfo;
begin
ShowMessage('ClassB.GetInfo');
end;
end.
ماهو الفرق إذا؟
هنا أنت دخلت في polymorphism وما هي فائدته.
هاك هذا المثال, شغله أولا ثم انظر الناتج, بعدها احذف virtual من الكلاس الام وoverride من الكلاسات الاخرى وشغل ثم لاحظ الفرق:
PHP كود :
uses
System.SysUtils,
System.Generics.Collections;
type
TVehicle = class
public
procedure Describe; virtual;
end;
TBus = class(TVehicle)
public
procedure Describe; override;
end;
TCar = class(TVehicle)
public
procedure Describe; override;
end;
TTruck = class(TVehicle)
public
procedure Describe; override;
end;
{ TVehicle }
procedure TVehicle.Describe;
begin
writeln('This is an unknown vehicle');
end;
{ TTruck }
procedure TTruck.Describe;
begin
writeln('This is a truck');
end;
{ TBus }
procedure TBus.Describe;
begin
writeln('This is a bus');
end;
{ TCar }
procedure TCar.Describe;
begin
writeln('This is a car');
end;
var
garage: TObjectList<TVehicle>;
i: integer;
begin
garage := TObjectList<TVehicle>.Create;
// add some vehicles to the garage
garage.AddRange([TCar.Create, TBus.Create, TCar.Create, TTruck.Create]);
// Listing the type of vehicles in the garage
for i := 0 to garage.Count - 1 do
garage.Items[i].Describe;
readln;
end.
بدون عمل overriding للاجراءات الناتج يكون هكذا:
إقتباس :This is an unknown vehicle
This is an unknown vehicle
This is an unknown vehicle
This is an unknown vehicle
وبعمل overriding يكون هكذا:
إقتباس :This is a car
This is a bus
This is a car
This is a truck
الله يفتح عليك ويبارك فيك
بدأت تصلنا اشعة الشمس (بدينا نفهموا), الحمدلله
يعني ممكن نديها قاعدة : اني ديما نستعمل virtual and override تحسبا لإستعمال تلك الطريقة مستقبلا , افضل من اني لا استعملهم ؟
ربي ينورك ويفرج عليك أخي الكريم
لما تكون method static يتم تحديد عنوانها من طرف compiler
أما method virtual فيتم تحديد عنوانها أثناء execution