ما الفرق بين virtual and static method ؟
#1
Question 
السلام عليكم ورحمة الله تعالى وبركاته

نعلم أن 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);

اين هو الفرق إذا ؟
الرد
#2
كل class method هي static بشكل افتراضي.

خاصية virtual توضع وراء أية method أو إجراء في كلاس ما إذا اردت من الكلاسات المنحدرة منها اعادة تعريف الاجراء, وليس شرط أن تكون class function أو class procedure.

مثلا في كلاس عادية:

PHP كود :
type
    TVehicle 
= class
      public
        procedure Movevirtual;
    end
بعدها كلاس أخرى ترثها وتعيد تعريف الاجراء Move بما يناسبها هي:
PHP كود :
type
    TCar 
= class(TVehicle)
      public
        procedure Moveoverride;
    end

في حالة كانت class function أو class procedure بغض النظر ان كانت virtual أو لا, يمكن استخدامها بدون انشاء object لذلك الكلاس, ففي مثالك لم تنشئ object أو instance للكلاس TClassA واستخدمت الاجراء مباشرة بعد ذكر اسم الكلاس.

مثالي ليس مناسب, لكن اتمنى ان تصل الفكرة.
الرد
#3
الله ينورك أخي سفيان

- نستعمل 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.

ماهو الفرق إذا؟
الرد
#4
هنا أنت دخلت في polymorphism وما هي فائدته.

هاك هذا المثال, شغله أولا ثم انظر الناتج, بعدها احذف virtual من الكلاس الام وoverride من الكلاسات الاخرى وشغل ثم لاحظ الفرق:
PHP كود :
uses
  System
.SysUtils,
  System.Generics.Collections;

type
  TVehicle 
= class
  public
    procedure Describevirtual;
  end;

  TBus = class(TVehicle)
  public
    procedure Describeoverride;
  end;

  TCar = class(TVehicle)
  public
    procedure Describeoverride;
  end;

  TTruck = class(TVehicle)
  public
    procedure Describeoverride;
  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
  garageTObjectList<TVehicle>;
  iinteger;

begin
  garage 
:= TObjectList<TVehicle>.Create;

  // add some vehicles to the garage
  garage.AddRange([TCar.CreateTBus.CreateTCar.CreateTTruck.Create]);

  // Listing the type of vehicles in the garage
  for := 0 to garage.Count 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
[-] كل من 1 user says قال شكرا ل sofiane201 على المشاركة المفيدة
  • MasteranyOne
الرد
#5
الله يفتح عليك ويبارك فيك

بدأت تصلنا اشعة الشمس (بدينا نفهموا), الحمدلله

يعني ممكن نديها قاعدة : اني ديما نستعمل virtual and override تحسبا لإستعمال تلك الطريقة مستقبلا , افضل من اني لا استعملهم ؟

ربي ينورك ويفرج عليك أخي الكريم
[-] كل من 1 user says قال شكرا ل MasteranyOne على المشاركة المفيدة
  • sofiane201
الرد
#6
لما تكون method static يتم تحديد عنوانها من طرف compiler
أما method virtual فيتم تحديد عنوانها أثناء execution
[-] كل من 2 users say قال شكرا ل ghostdz على المشاركة المفيدة
  • MasteranyOne, sofiane201
الرد


التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم