![]() |
|
الفئات ومقدمة إلى البرمجة كائنية التوجه - نسخة قابلة للطباعة +- delphi4arab منتديات دلفي للعرب (https://delphi4arab.net/forum) +-- قسم : منتديات دلفي الأخرى (https://delphi4arab.net/forum/forumdisplay.php?fid=4) +--- قسم : برمجة الويب بدلفي وDelphi .NET و Oxygen (https://delphi4arab.net/forum/forumdisplay.php?fid=29) +--- الموضوع : الفئات ومقدمة إلى البرمجة كائنية التوجه (/showthread.php?tid=3235) |
الفئات ومقدمة إلى البرمجة كائنية التوجه - زكيري عبدالعالي - 25-06-2011 ألسلام عليكم و رحمة الله تعالى و براكته ساعتمد في شرحي و تعاريفي على كتابين الولل للاستاذ علي عروة و الثاني للاستاذ احمد جمال خليفة سنقوم بشرح مفصل للبرمجة الشيئية للدلفي و البريسم غرضية التوجة في دلفي object-oriented in Delphi : إن معظم اللغات الحديثة تدعم البرمجة غرضية التوجة (OOP) أو object-oriented programming , حتى أن مقدار دعم اللغة للـ OOP أصبح ينظر إلية في كثير من الأحيان كمقياس يعبر عن أهمية اللغة . تعتمد البرمجة غرضية التوجة على ثلاث مفاهيم أساسية سنعالجها في هذا الفصل : - التغليف encapsulation . - الوراثة inheritance . - تعددية الأشكال polymorphism . دلفي هي توسيع غرضي_التوجة للغة باسكال التقليدية .وما **** التنوية إلية هنا أن الصياغة النحوية للغة الباسكال مشهورة بإنها صياغة أكثر وضوحا وقابلية للقراءة من معظم اللغات الأخرى (ولنقل مثلا لغة C ) , وبالتالي كمية أكبر من الحشو من أجل الحصول على شفرة مقروءة تشبة الكلام العادي بحيث يمكن فهمها وتذكرها بشكل سريع ومنتظم وهذا مما يقل من الوقوع بالأخطاء . كما أن التوسع الغرضي_التوحه لهذة الغة بإعتراف الجميع لا يقل أهمية عن الموجود في النسل الحالي للغات البرمجة الغرضية من Java حتى C# الفئات ومقدمة إلى البرمجة كائنية التوجه - kachwahed - 25-06-2011 وعليكم السلام ورحمة الله وبركاته يعتبر البعض أن مجرد إمكانية التوليف باستخدام مناهج متسلسلة (البرمجة الإجرائية Procedural) خطر على الشركة والمبرمج، وهو مما يعاب على [مستخدمي] دلفي! ما رأيك؟ الفئات ومقدمة إلى البرمجة كائنية التوجه - زكيري عبدالعالي - 25-06-2011 شكرا اخي الكريم شكرا على نقل المشارك الى موضوع جديد بقية مشارك اخرى ****ان تقوم بنقلها فصلحباتي محدودة جدا موافق 100" إقتباس :وهو مما يعاب على [مستخدمي] دلفي!لا فهناك الكثير يعتمدون على OOP و من بينهم انا ودعت البرمجة باستخدام المناهج منذوا فترة طويلة الا للبرامجة القديمة التي لم نغيرها و الان الحمد لله مع الدوت نت انا مجبر على هذا النوع من البرمجة لان اغلب المشاريع اما تعتمد على ORM في التعامل مع قواعد البيان او انه اختارفية جدا وهو المشروع الذي اعمل عليه حاليا في WPF لكني مبتدا . ومكونات الدلفي VCL ايضا لم تعطي امكانيت التعامل مع الاشياء عن طريق خاصية مثل ماهو في البريسم datasours سنحاول قدر المستطاع شرح هذا لكي يستطيع الجميع التنقل بين اللعات دون مشكل c# prism java الفئات ومقدمة إلى البرمجة كائنية التوجه - زكيري عبدالعالي - 25-06-2011 يمكن ان يحتوي البرنامج على عدة فئات ، ويمكن ان تحتوي الفئة ايضاً على عدة فئات بداخله ، في .Project من New Class منفصل يمكنك اضافة Class حالة رغبتك في عمل يتم تعريف الفئة باستخدام الكلمة المحجوزة class سنقوم بادراج فئة جديدة ،ونسميها باسم MyClass سنجد الكود التالي موجوداً بصورة افتراضية: خاص بالبريسم الجزء الأول الذي يحدد ال namespace ضروري ، حيث يعني هذا ان جميع الفئات الموجودة تحت نفس namespace يمكنها رؤية بعضها الآخر ، لذا سنتمكن من التعامل مع الفئة الجديدة من خلال main الخاصة بنا في الفئة الاساسية المسماه Program عريف الأصناف في دلفي : لتعريف صنف جديد في دلفي , دعنا نتذكر أن الصنف يحوي شيئين مهمين هما الحقول (بيانات الصنف) والمناهج (عمليات الصنف) . بناء صنف جديد موضوع سهل في دلفي . DELPHI كود : unit MyClassFile;
interface
type
Mycalss = class end;
implementation
end.PRISM كود : namespace MyProject;
interface
type
MyClass = class end;
implementation
end.إذا فكرنا بناءً على ما سبق ماذا نحتاج لنعرف صنف جديد , لوجدنا أننا نريد تعريف الحقول التي يحويها هذا الصنف والعمليات التي يستطيع إنجازها , وبالتأكيد نعرف له إسما فريدا خاص به . الحقول هي عبارة عن متحولات عادية , والعمليات هي عبارة عن مناهج (أي توابع أو إجراءات) . تنسيق هذا التعريف يتم بصورة بسيطة – بإن نذكر في قسم Type إسم الصنف محدداً بالكلمة المفتاحية Class ونتبعه مباشرة بتعريف الحقول الخاصة به , ثم رؤوس المناهج التي يعرفها , وبالتأكيد ننهي ذلك بـ الفئات ومقدمة إلى البرمجة كائنية التوجه - زكيري عبدالعالي - 25-06-2011 تعريف حقل صنف DELPHI كود : MyClass = class
private _myField: string;
published property MyField : string read _myField write _myField;
end;كود : MyClass = class
private _mMyField: string;
public property MyField : string read _mMyField write _mMyField;
end;إذا ضغطت Ctrl+Shift+C عندما يكون المؤشر ضمن تعريف الصنف , فإن ميزة تكميل التعريف في دلفي سوف تقوم تلقائيا بمساعدتك وتوليد هيكل التعريف الخاص بالمناهج التي قمت بتعريفها في الصنف . كما تلاحضون اننا انشانا حقل من نوع string وخاص بالصنف . الفئات ومقدمة إلى البرمجة كائنية التوجه - زكيري عبدالعالي - 25-06-2011 كما تلاحضون اننا انشانا حقل من نوع string وخاص بالصنف و نستطيع الوصول اليه عن طريق خاصية (يمكن ان يكون تابع) سواء للقراء او الكتابة في هذا الحفل . *- تغيير قيمة الحقل DELPHI كود : var MyObeject : MyClassFile.Mycalss;
begin
MyObeject := MyClassFile.Mycalss.Create();
MyObeject.MyField:='FieldValue';
end;كود : var MyObject := new MyProject.MyClass();
MyObject.MyField := 'FieldValue';التغليف Encapsulation : تعتمد فكرة غرضية التوجة على إخفاء البيانات . وتستخدم الأصناف لتحقيق ذلك . يتم إخفاء البيانات داخل الأصناف الخاصة بها , أو نقول يتم تغليف البيانات داخل الأصناف . عادة يتم توضيح هذة الفكرة بإستخدام ما يسمى الصناديق السوداء (black boxes) , حيث لا تضطر أن تعرف كيف تتم الأمور بالداخل وما هي المحتويات الداخلية , وكل ما يهمك هو كيف تتعامل مع واجهة الصندوق الأسود وتعطية معطياتك وتأخذ النتائج بغض النظر عن ما يتم في الداخل . إن ما يهمك فعليا من الصندوق هو آلية التعامل معة (مع واجهتة) ولا تعطي إهتماما كبيرا عن تفاصيل داخل الصندوق , مثلا يهمك أن تتفرج على البرامج المفضله على التلفزيون وأن تعرف تغيير المحطات وإطفاءة وتشغيلة , بغض النظر عن فهم الدارات الداخلية المكونة للتلفزيون .. الفئات ومقدمة إلى البرمجة كائنية التوجه - زكيري عبدالعالي - 26-06-2011 ملاحضة هناك ثلاث اشكال للتعريف بالحقول 1- published property MyField : string read _myField write _myField; 2- published property MyField : string read _myField write SetMyField; 3- published property MyField : string read GetMyField write SetMyField; لحالة الأولى : وهي أبسط الحالات , أن نقوم بتعريف متحول ما _myField مثلا من أجل القراءة والكتابة , بدون إستخدام أي منهج , القراءة تتم منه والكتابة إلية , وطبعا لا يمكن هنا التأكد من صحة الإدخال , أو إرفاق إدخال أو إخراج القيمة بحدث ما . الحالة الثانية :قمنا بالقراءة من متحول (_myField ) بشكل طبيعي مثل الحالة الأولى , حيث أنة في كثير من الأحيان لا نحتاج التأكد من صحة الإخراج طالما كنا قد تأكدنا من صحة الإدخال منذ البداية . أما الكتابة فتتم بإستخدام الإجرائية SetMyField, وهنا نستطيع التأكد من صلاحية الأدخال أو إرفاق الإدخال بأحداث ما (إلغاء تعطيل خواص معينة بعد الإدخال مثلا) , وبالطبع هذة الحالة مستخدمة كثيرا على عكس الحالة الأولى . الحالة الثالثة : إستخدمنا التابع GetMyField للإدخال والإجرائية SetMyFieldللإخراج , وهي الحالة العامة . الباني Constructor : الباني هو منهج خاص يستخدم لحجز الذاكرة لمنتسخ من صنف ليصبح جاهزاً للإستخدام , وكنا قد سميناه المنهج Create في مامضى , الحقيقة التي ****ك أن تعرفها عن الباني أنة يعيد الغرض كقيمة جاهزة للإستخدام حيث نستطيع نسية إلى متحول موجود لكي نستخدمة لاحقا . أي كأنة تابع قيمتة المعادة هي الغرض نفسة DELPHI في الدلفي كلمة constructor هي التي تستعمل لتعريف باني او مشيد كود : unit MyClassFile;
interface
type
Mycalss = class
private _mMyField: string;
public property MyField : string read _mMyField write _mMyField;
public constructor Create();
end;
implementation
constructor Mycalss.Create();
begin
Self._mMyField := 'قيمة افتراضية للحقل ';
end;
end.لو قمنا بانشاء شئ جديد او غرض جديد و عرضنا حقله بالطريقة التالية كود : procedure TForm1.Button1Click(Sender: TObject);
var MyObeject : MyClassFile.Mycalss;
begin
MyObeject := MyClassFile.Mycalss.Create();
showmessage(MyObeject.MyField);
end;إقتباس :قيمة افتراضية للحقل PRISM كود : namespace MyProject;
interface
type
MyClass = class
private _mMyField: string;
public property MyField : string read _mMyField write _mMyField;
constructor();
end;
implementation
constructor MyClass();
begin
self._mMyField := 'قيمة افتراضية للحقل ';
end;
end.كود : method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);
begin
var MyObject := new MyProject.MyClass();
MessageBox.Show(MyObject.MyField);
end;الفئات ومقدمة إلى البرمجة كائنية التوجه - زكيري عبدالعالي - 26-06-2011 يمكن ايضاً ان يستقبل الباني بارميترس، فمثلاً نريد تغيير القيمة الافتراضية بقيمة نحددها في كل مرة ننشا الغرض . [COLOR="DarkOrange"]ملاحضة هامة سنرجع اليها بعد قليل يكن للصنف ان يحتوي على عدة مشيدلت او بواني [/COLOR] كود : unit MyClassFile;
interface
type
Mycalss = class
private _mMyField: string;
public property MyField : string read _mMyField write _mMyField;
public constructor Create(); overload ;
public constructor Create( mYFieldVariable : string ) ; overload ;
end;
implementation
constructor Mycalss.Create();
begin
Self._mMyField := 'قيمة افتراضية للحقل ';
end;
constructor Mycalss.Create(mYFieldVariable : string);
begin
Self._mMyField := mYFieldVariable;
end;
end.كود : procedure TForm1.Button1Click(Sender: TObject);
var MyObeject : MyClassFile.Mycalss;
begin
MyObeject := MyClassFile.Mycalss.Create('تمرير فيمة افتراضية جديدة');
showmessage(MyObeject.MyField);
end;PRISM كود : namespace MyProject;
interface
type
MyClass = class
private _mMyField: string;
public property MyField : string read _mMyField write _mMyField;
constructor();
constructor ( mYFieldVariable : string ) ;
end;
implementation
constructor MyClass();
begin
self._mMyField := 'قيمة افتراضية للحقل ';
end;
constructor MyClass( mYFieldVariable : string ) ;
begin
Self._mMyField := mYFieldVariable;
end;
end.كود : method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);
begin
var MyObject := new MyProject.MyClass('تمرير فيمة افتراضية جديدة');
MessageBox.Show(MyObject.MyField);
end;الفئات ومقدمة إلى البرمجة كائنية التوجه - زكيري عبدالعالي - 29-06-2011 المهدمات Destructor عكس ال ،Constructor يتم اطلاق هذا الحدث مع انهاء استخدام الObject يمكن كتابة هادم خاص لة . ويقوم بالعمل المعاكس حيث يحرر أي ذاكرة قام الباني بحجزها ولم تحرر فيما بعد . ويبدأ بالكلمة المفتاحية destructor و يكون إسمة Destroy . سترى لاحقا إمكانية إستخدام الهادم القديم ضمن الجديد من أجل أن يقوم الصنف ببعض عمليات التنظيف دون أن نشغل بالنا فيها من جديد . لا تستخدم أبدا إسم للهادم غير الإسم Destroy , لإن الأغراض يتم تحريرها عادة بالمنهج الشهير Free ومبدأ هذا المنهج(Free): هو إختبار إذا كانت قيمة الغرض Nil قبل أن يستدعي المنهج الهادم Destroy , وبالتالي فإن Free لن يتعرف على الهادم الجديد الذي قمنا ببناءة إذا لم يكن إسمة Destroy وستنتج أخطاء . إن Free هي منهج للصنف الأب Tobject والذي ترثة كل الأغراض الأخرى . والجدير بالذكر هنا أن Free لن تقوم بضبط قيمة الغرض إلى Nil بعد تحرير الذاكرة الخاصة به .لذلك عليك أن تقوم بذلك بنفسك والسبب بسيط أن الغرض لن يعرف ما هي المتحولات التي نسبت إلية , ولن يستطيع التأكد من أنه ضبط قيمة جميع هذة المتحولات إلى Nil , لذلك تركت العملية إلى المستخدم , ولكن دلفي تملك بعض الدوال ال****** هنا مثل الدالة FreeAndNil التي قد تساعد أحيانا . حيث أنها تحرر الغرض وتلغي المرجع الذي يشير إلية (يصبح المؤشر معرفا مثل أي متحول ولكنة لايشير إلى أي قيمة بالذاكرة ) . DELPHI كود : published Destructor Destroy;كود : destructor Mycalss.Destroy;
begin
Self._mMyField := '';
ShowMessage('هدم الكائن');
end;كود : procedure TForm1.Button1Click(Sender: TObject);
var MyObeject : MyClassFile.Mycalss;
begin
MyObeject := MyClassFile.Mycalss.Create('تمرير فيمة افتراضية جديدة');
showmessage(MyObeject.MyField);
FreeAndNil(MyObeject);
end;PRISM كود : public finalizer Finalize;كود : finalizer MyClass.Finalize;
begin
Self._mMyField := nil;
MessageBox.Show('هدم الكائن');
end;كود : method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);
begin
var MyObject := new MyProject.MyClass('تمرير فيمة افتراضية جديدة');
MessageBox.Show(MyObject.MyField);
end;الفئات ومقدمة إلى البرمجة كائنية التوجه - زكيري عبدالعالي - 30-06-2011 الكلمة المحجوزة self هي تمثل اسم اختصار للصنف المحدد و استخدامها سيكون مناسب دائماً ، ابسط اسباب ذلك هو اظهار قائمة بالعناصر الموجودة في الاوبجكت وقت البرمجة منذ للحظة التي تكتب فيها self. Static Class لا بد ان تكون جميع المتغيرات والدوال فيه من نوع static اضف إلى ذلك فإنه ليس من المنطقي تعريف object من هذا الفئة Class باستخدامNEW او CREATE DELPHI كود : MyStaticClass = class(TObject)
private {$HINTS OFF} constructor Create; {$HINTS ON}
public class var MyVariable: string;
public class function MyStaticMethod(MyParametre : string):string;
end;كود : constructor MyStaticClass.Create;
begin
end;
class function MyStaticClass.MyStaticMethod(MyParametre: string): string;
begin
Result := Copy(MyParametre,0,7);
end;كود : procedure TForm1.Button2Click(Sender: TObject);
begin
MyStaticClass.MyVariable:='zekiri abdelali';
showmessage(MyStaticClass.MyStaticMethod(MyStaticClass.MyVariable));
end;PRISM كود : MyStaticClass = static class
public constructor ();
public class var MyVariable: string;
public class method MyStaticMethod(MyParametre : string):string;
end;كود : constructor MyStaticClass() ;begin end;
class method MyStaticClass.MyStaticMethod(MyParametre : string): string;
begin
result := MyParametre.Split(' ')[0];
end;كود : method MainForm.button2_Click(sender: System.Object; e: System.EventArgs);
begin
MyStaticClass.MyVariable:='zekiri abdelali';
MessageBox.Show(MyStaticClass.MyStaticMethod(MyStaticClass.MyVariable));
end; |