30-06-16, 03:49 AM
الصفحات : 1 2
30-06-16, 04:11 AM
Abstract Classes تمكنك من اضافة الكثير من الوظائف للتطبيق بدون الاضرار بالكلاسات التي اشتقتها (انا اسميها الابناء)
اذ ان تحديثك للفئة القاعدية فالتحديثات ستشمل كل الفئات الابناء
بينما اذا استخدمت Interfases فانك ستكون مجبرا على اعادة تعريف الطرق الجديدة في كل الفئات الابناء.
انا ارى بنظري ان استخدام Abstract Classe هو انسب للتعامل مع كل الفئات ذات القرابة , اي ذات الارتباط ببعضها
بينما Interfaces تعتبر حل امثل للفئات غير المرتبطة.
لتتضح الفكرة اكثر دعني اضرب المثال التالي
لو فرضنا ان لدينا فئة الطائر و فئة الطائرة و كلا الفئتين يمتلكان الطريقة Flay فانه من السخافة ان نقول ان الطائرة ترث من الطائر فقط لانها تمتلك خاصية الطيران , فانه من المناسب اكثر ان تكون هذه الطريقة موجودة في Interface
و كل فئة تستخدم الطريقة بما يناسبها
اذا اردنا نقدم تعميما اكثر لحل هذه المشكلة هناك قول اخر هو لما لا يكون لدينا Abstract Classes يشمل على كل الوظائف ليساعدنا في التعديلات المستقبلية توفيرا للوقت اذ انني لن اضطر لتعديل كل الفئات الاخرى التي تشتق من هذه الفئة (هل تذكر قولنا عن الفئات ذات القرابة و الارتباط) كما انها تسمح لنا باستخدام جزئيات فقط من الوظائف.
الخيار يتوقف عليك و على حسب حاجتك (لا تغفل الجزئية التي تحدث عنها الاخ الشاكي).
نستطيع الاعتماد على Interfaces و كذلك Abstract Classes و كذلك يمكن المزج بينهما.
اذ ان تحديثك للفئة القاعدية فالتحديثات ستشمل كل الفئات الابناء
بينما اذا استخدمت Interfases فانك ستكون مجبرا على اعادة تعريف الطرق الجديدة في كل الفئات الابناء.
انا ارى بنظري ان استخدام Abstract Classe هو انسب للتعامل مع كل الفئات ذات القرابة , اي ذات الارتباط ببعضها
بينما Interfaces تعتبر حل امثل للفئات غير المرتبطة.
لتتضح الفكرة اكثر دعني اضرب المثال التالي
لو فرضنا ان لدينا فئة الطائر و فئة الطائرة و كلا الفئتين يمتلكان الطريقة Flay فانه من السخافة ان نقول ان الطائرة ترث من الطائر فقط لانها تمتلك خاصية الطيران , فانه من المناسب اكثر ان تكون هذه الطريقة موجودة في Interface
و كل فئة تستخدم الطريقة بما يناسبها
اذا اردنا نقدم تعميما اكثر لحل هذه المشكلة هناك قول اخر هو لما لا يكون لدينا Abstract Classes يشمل على كل الوظائف ليساعدنا في التعديلات المستقبلية توفيرا للوقت اذ انني لن اضطر لتعديل كل الفئات الاخرى التي تشتق من هذه الفئة (هل تذكر قولنا عن الفئات ذات القرابة و الارتباط) كما انها تسمح لنا باستخدام جزئيات فقط من الوظائف.
الخيار يتوقف عليك و على حسب حاجتك (لا تغفل الجزئية التي تحدث عنها الاخ الشاكي).
نستطيع الاعتماد على Interfaces و كذلك Abstract Classes و كذلك يمكن المزج بينهما.
03-07-16, 04:39 AM
معلومة مفيدة اخي خضر ..
واضيف كذلك انه عند تعريف Abstract Class وClass عادية مشتقة من الـ Abstract بهذا الشكل:
لو عرفنا Instance من الAbstract class بواسطة طريقة الPointing (كما ذكر اخونا خضر في المشاركة السابقة) ،
ثم لو قمنا بالاستعلام عن الType بهذا الشكل
الـ Type المرجع سيكون Ahmed وليس Name ، ذلك بسبب ان الـ Interface والـ Abstract في حالة الPointing، كلاهما يقومان بإرجاع الـ Concrete type
وفي مثاالنا اعلاه الـ Concrete type هو Ahmed بسبب ان الـ Instance مشار اليه بواسطة متغير من نوع Abstract
--
ومع ذلك ، عند استخدام المقارنة بالـ Type بواسطة المعامل Is .. سنجد ان الرسالتين في الاسفل سيتم طباعتهما :
نعم ، المعامل Is يرجع True سواء قارنت الـ object بالـ concrete class او بالـ Abtract class
طبعا نفس الموضوع بالضبط يحصل عند استخدام الانترفيس
واضيف كذلك انه عند تعريف Abstract Class وClass عادية مشتقة من الـ Abstract بهذا الشكل:
PHP كود :
//abstract
abstract class Name
{
}
//normal class (inherts from Name)
class Ahemd : Name
{
}
لو عرفنا Instance من الAbstract class بواسطة طريقة الPointing (كما ذكر اخونا خضر في المشاركة السابقة) ،
PHP كود :
Name n = new Ahemd();
ثم لو قمنا بالاستعلام عن الType بهذا الشكل
PHP كود :
Name n = new Ahemd();
MessageBox.Show( n.GetType().Tostring() );//will return the concrete class (which is Ahmed)
الـ Type المرجع سيكون Ahmed وليس Name ، ذلك بسبب ان الـ Interface والـ Abstract في حالة الPointing، كلاهما يقومان بإرجاع الـ Concrete type
وفي مثاالنا اعلاه الـ Concrete type هو Ahmed بسبب ان الـ Instance مشار اليه بواسطة متغير من نوع Abstract

--
ومع ذلك ، عند استخدام المقارنة بالـ Type بواسطة المعامل Is .. سنجد ان الرسالتين في الاسفل سيتم طباعتهما :
PHP كود :
Name n = new Ahemd();
if (n is Name)
{
MessageBox.Show("Hi"); //will be printed
}
if (n is Ahemd)
{
MessageBox.Show("Hi"); //will be printed
}
نعم ، المعامل Is يرجع True سواء قارنت الـ object بالـ concrete class او بالـ Abtract class
طبعا نفس الموضوع بالضبط يحصل عند استخدام الانترفيس
03-07-16, 06:52 AM
بما ان الموضوع انقلب الى نقاش تبادل خبرات ..
دعوني اعرض لكم احدى استخداماتي للـ Interface وايضا الـ Base Class
المشروع الذي اعمل عليه حاليا يحتوي على الكثير من الانظمة .. وهذا شيئ طبيعي لان المشروع عبارة عن لعبة ، ودائما الالعاب تحتوي على الكثير من الانظمة التي عليك مزامنتها مع الاحداث التي تحصل باللعبة
مثلا عند انفجار قنبلة في اللعبة ، الكثير من الانظمة يجب ان تعمل في وقت واحد ، منهم
Damage System
VisualEffect System
SoundEffect System
Score System
هنا نرى ان هذه الانظمة يجب ان تعمل في وقت واحد عند انفجار القنبلة ، وبالطبع يجب ان تتفاعل هذه الانظمة بشكل متزامن وصحيح بين بعضها البعض لذلك -في بعض الاحيان- تحتاج الى ارسال Message بينها ، وايضا تحتاج الى جهة او جهات تستقبل هذه الرسالة وتعالجها ..
لهذا الغرض ـ نقوم بتعريف Interface لنستعمله لاحقا في التنصت على الرسائل ، ونقوم بتعريف Base Class لاستخدامها في تكوين الرسائل (كما بالصورة)
اذن ، الانظمة التي بحاجة الى التنصت على الرسائل تقوم بوراثة الـ Interface ، كما هو الحال في الـ Damage System :
وفي احدى سكربتات اللعبة ، توجد الدالة التالية التي تتنفذ عند حصول اي انفجار في اللعبة ، يقوم هذا الكود بارسال رسالة الى جميع الانظمة التي تقوم بالتنصت (التي تشتق من الانترفيس IGameListener) :
وبالتالي ، جميع انظمة الصوت وانظمة المؤثرات البصرية وغيرها من الانظمة ستستلم هذه الرسالة وتقوم بالتفاعل مع الانفجار
وان سالتني كيف شكل الدالة SendMessageToAll ، تفضل
الدالة فقط من سطرين :
ووظيفتها هي الدوران وجلب جميع الـ classes التي تشتق من الـ Interface المسمى IGameListener واستدعاء الدالة Listener وتمرير الرسالة لها
لماذا تم عمل IGameListiner كـ Interface ؟؟
لانها تحقق علاقة can-do مع الsystem
Damage System can Listen
بينما تم عمل MessageBase كـ Class بسبب ان العلاقة هي Is-A
BombMessage is a message
--
هذا كان احد الامثلة التطبيقية للـ Interface والوراثة
ايضا اذا كان عند الاخوان اي مثال تطبيقي اخر يمكنه المشاركة به لنستفيد
دعوني اعرض لكم احدى استخداماتي للـ Interface وايضا الـ Base Class
المشروع الذي اعمل عليه حاليا يحتوي على الكثير من الانظمة .. وهذا شيئ طبيعي لان المشروع عبارة عن لعبة ، ودائما الالعاب تحتوي على الكثير من الانظمة التي عليك مزامنتها مع الاحداث التي تحصل باللعبة
مثلا عند انفجار قنبلة في اللعبة ، الكثير من الانظمة يجب ان تعمل في وقت واحد ، منهم
Damage System
VisualEffect System
SoundEffect System
Score System
هنا نرى ان هذه الانظمة يجب ان تعمل في وقت واحد عند انفجار القنبلة ، وبالطبع يجب ان تتفاعل هذه الانظمة بشكل متزامن وصحيح بين بعضها البعض لذلك -في بعض الاحيان- تحتاج الى ارسال Message بينها ، وايضا تحتاج الى جهة او جهات تستقبل هذه الرسالة وتعالجها ..
لهذا الغرض ـ نقوم بتعريف Interface لنستعمله لاحقا في التنصت على الرسائل ، ونقوم بتعريف Base Class لاستخدامها في تكوين الرسائل (كما بالصورة)
اذن ، الانظمة التي بحاجة الى التنصت على الرسائل تقوم بوراثة الـ Interface ، كما هو الحال في الـ Damage System :
وفي احدى سكربتات اللعبة ، توجد الدالة التالية التي تتنفذ عند حصول اي انفجار في اللعبة ، يقوم هذا الكود بارسال رسالة الى جميع الانظمة التي تقوم بالتنصت (التي تشتق من الانترفيس IGameListener) :
وبالتالي ، جميع انظمة الصوت وانظمة المؤثرات البصرية وغيرها من الانظمة ستستلم هذه الرسالة وتقوم بالتفاعل مع الانفجار

وان سالتني كيف شكل الدالة SendMessageToAll ، تفضل

الدالة فقط من سطرين :
ووظيفتها هي الدوران وجلب جميع الـ classes التي تشتق من الـ Interface المسمى IGameListener واستدعاء الدالة Listener وتمرير الرسالة لها

لماذا تم عمل IGameListiner كـ Interface ؟؟
لانها تحقق علاقة can-do مع الsystem
Damage System can Listen
بينما تم عمل MessageBase كـ Class بسبب ان العلاقة هي Is-A
BombMessage is a message
--
هذا كان احد الامثلة التطبيقية للـ Interface والوراثة
ايضا اذا كان عند الاخوان اي مثال تطبيقي اخر يمكنه المشاركة به لنستفيد

الصفحات : 1 2