![]() |
|
[نقاش] الفرق بين الـ Interface , Abstract Class , Base Class , Sealed Class - نسخة قابلة للطباعة +- منتدى فيجوال بيسك لكل العرب | منتدى المبرمجين العرب (http://vb4arb.com/vb) +-- قسم : قسم لغة السي شارب C#.NET (http://vb4arb.com/vb/forumdisplay.php?fid=175) +--- قسم : قسم مقالات C#.NET (http://vb4arb.com/vb/forumdisplay.php?fid=177) +--- الموضوع : [نقاش] الفرق بين الـ Interface , Abstract Class , Base Class , Sealed Class (/showthread.php?tid=16294) الصفحات:
1
2
|
[نقاش] الفرق بين الـ Interface , Abstract Class , Base Class , Sealed Class - الشاكي لله - 29-06-16 السلام عليكم ورحمة الله وبركاته
في هذا الرد سنوضح الفرق بين الـ Interface والـ Class من ناحية الوراثة ـ
بينما بقية المقارنات مشروحة في الردود تحت بواسطة الاعضاء الكرام .. احيانا نحتاج الى استعمال مبدأ الوراثة ، ولكن معظمنا لايعرف ماذا يستخدم للوراثة ، هل يستخدم الـ Interface او يستخدم الـ Class ؟ ولكن المقالة التالية ستوضح بشكل قاطع متى يستخدم الـ Class ومتى يستخدم الـ Interface سؤال / متى استخدم الوراثة من كلاس (Inheritance from Base Class) ومتى استخدم الوراثة من الواجهات البرمجية(Inheritance from Interface) ؟ او ممكن اعادة صياغة السؤال بضمير المتحدث :- سؤال / انا بحاجة لتطبيق مبدأ الوراثة ، فهل اقوم بانشاء Base Class او اقوم بانشاء Interface ؟ ----------------------------------------------- الجواب :- المفهومان يتشابهان الى حد كبير لدرجة انك احيانا لا تعلم ايهما تستخدم .. لذلك وجدت العلاقة التالية التي تحدد لك بوضوح ايهما يجدر استعماله :- العلاقة الاولى : Is-a ، عندما تكون لدينا هذه العلاقة بين اثنين Types ، هنا نقوم بانشاء Base Class ونقوم بالاشتقاق منها ((Inheritance from Base Class) العلاقة الثانية : can-do ـ عندما تكون لدينا هذه العلاقة بين اثنين Types ، هنا نقوم بانشاء واجهة برمجية ونقوم بالاشتقاق منها (Inheritance from Interface) -- مثال من مكتبات ال.NET ... هناك كلاس اسمه Bitmap ، هذا الكلاس مشتق من الكلاس Image لماذا قام مصمم اللغة بتعريف Class باسم Image ؟، لماذا لم يقم بتعريف Image كـ Interface ؟ السبب لان العلاقة المستخدمة بين الكلاسين هي Is-a >> Bitmap Is an Image وفي نفس الوقت ، الكلاس Bitmap مشتق كذلك من واجهة برمجية تسمى IDisposable وايضا من واجهة اخرى تسمى ICloneable لماذا قام مصمم اللغة بتعريف Interface باسم IDisposable ، لماذا لم يقم بتعريف IDisposable كـ Class ؟ لان العلاقة المستخدمة هنا can-do >> Bitmap can do Dispose Bitmap can do Clone اذن الشكل العام للكلاس Bitmap سيكون كالتالي :- PHP كود : public class Bitmap : Image , IDisposable , ICloneable-- مثال اخر/ انظر هذا الكود :- PHP كود : class Ahmed : Person, IWalk, ISleep, ISwimفي الكود السابق هناك كلاس باسم Ahmed وهو يشتق من Base Class المسمى Person ، ويشتق ايضا من ثلاثة Interface السبب في اشتقاق Ahmed من الكلاس Person هو وجود علاقة Is-a >> ِAhemd is a Person بينما السبب في الاشتقاق من الInterfaces المسميات IWalk و IEat و ISleep هو وجود العلاقة can-do >> Ahmed can walk Ahmed can eat Ahmed can sleep لذلك يجب ان تُعرًف Person كـ Class ، لانها تحقق علاقة Is- a
بينما يجب عليك ان تُعرًف IWalk و IEat و ISleep كـ Interface ، لانهم يحققون علاقة can- do
وهذا كود تعريفهم :- PHP كود : //base class-- الخاتمة :- دائما عندما تقوم بكتابة اكوادك وعندما تكون بحاجة لاستعمال مبدأ الوراثة ، يجدر بك ان تعرف متى تقوم بانشاء Interface و متى تقوم بانشاء Base Class وذلك باستخدام العلاقتين اعلاه . تحياتي[/b] RE: متى استخدم الـ Interface ومتى استخدم الـ Class - ابو ليلى - 29-06-16 كلام جميل اخي الشاكي و خصوصا عندما تريد عمل مبدأ الوراثة المتعددة كما تعلم الوراثة المتعددة غير مدعومة في عملنا على #C لذلك اتى مبدأ تطبيق الواجهات حل سحري لتلافي القصر Implement Interfaces مثلا لو كان لدي كلاسين كما يلي PHP كود : Class FirstClass { }فانني لن استطيع تطبيق ما يلي PHP كود : class NewClass : FirstClass, SecondClass { } PHP كود : interface X { }يصبح من السهل علي الاستفادة منهما كما يلي PHP كود : class NewClass : X, Y { } كما يمكنني ايضا وراثة الكلاس و تطبيق الواجهة في نفس الوقت كما يلي PHP كود : class NewClass : FirstClass, X { } و بقيت الاشارة الى ان Interface تحتوي فقط على على طرق و خصائص و متغيرات بدون كود فقط تمهيد لها و باعادة تطبيقها يمكنك كتابة الاكواد المناسبة لهذه الطرق كما تشاء. بعكس Class الذي يحتوي على كل شيئ. RE: متى استخدم الـ Interface ومتى استخدم الـ Class - الشاكي لله - 29-06-16 (29-06-16, 02:15 AM)ابو ليلى كتب : ^ جزاك الله خيرا على هذه المداخلة القيمة هذا الرد بمثابة درس كامل عن الInterface بارك الله فيك -- بقي شيئ واحد اعتقد يجب توضيجه للجميع بخصوص الInterface ماهي الفائدة العملية من الـ Interface ؟ كنت حاب اجاوب على هذا السؤال ، لكن مو وقته حاليا ..
RE: متى استخدم الـ Interface ومتى استخدم الـ Class - ابو ليلى - 29-06-16 الفوائد كثيرة اخي و خصوصا اذا كنت من اصحاب الطرق التوسعية انا استخدمتها في تقنية Plugins لتوظيف طرق جديدة داخل التطبيق و العملية جدا ممتعة و رهيبة من خلال Interfaces RE: متى استخدم الـ Interface ومتى استخدم الـ Class - الشاكي لله - 29-06-16 ^ يامحاسن الصدف ... انا ايضا تعاملت مع الPlugin بالـ Reflector ولكن ليس باستعمال الـ Interface بل باستعمال الـ Abstract class (اخت الـ Interface بالرضاعة )والسبب في ذلك ان الInterface لاتدعم كتابة المتغيرات بداخلها ، وهذا سبب لي مشكلة مثلا كنت اريد اضافة متغير Name بهذا الشكل PHP كود : interface IPluginالا اننا نعرف ان الكود اعلاه بيسبب مشكلة ، لان الInterface لاتدعم ذلك وحتى لو قمت بتحويل Name الى Property سيبب ذلك مشكلة وهو انني سأضطر الى اعادة تعريف للخاصية في الكلاس الجديد (بالعربي ، مااستفدت شيئ )بالاضافة الى ذلك ، لو طبقنا العلاقتين المذكورتين بالموضوع ، سنجد ان علاقة Is- a هي التي تصلح لموضوع الPlugin لو عرفت Plugin باسم MyPlugin فيجب ان تستورث من Class لان العلاقة ستصبح >>> MyPlugin Is a Plugin ![]() MyPlugin can Plugin(لغويا غير ممكنة ، لذلك العلاقة لاتصلح) اذن العلاقة هي Is- A فيجب الاشتقاق من Class .. ولكن المشكلة بالـ classes العادية ان اكوادها ثابتة ولاتناسب موضوع الPlugin لاننا نحتاج الى Type يمكننا من عمل Re-Implemented لاستعماله كقالب للcasting او لاستعماله في Plugin اخرى .. ولكن -لحسن الحظ- Abstract class هو المنقذ [/b]PHP كود : abstract class PluginBaseRE: متى استخدم الـ Interface ومتى استخدم الـ Class - الوادي - 29-06-16 أساتذة اجتمعوا في موضوع........ RE: [مقال] متى استخدم الـ Interface ومتى استخدم الـ Class - Sajad - 29-06-16 السلام عليكم جزاكم الله خيرا على هذا النقاش الجميل أحب أن اضيف بعض المعلومات بخصوص الـ interface لا يمكن انشاء instance من interface PHP كود : IC c=new IC(); // Error PHP كود : interface ICPHP كود : interface ICلذا عند استخدام الدوال في الـ class سيكون عليك لزاماً أن تعرف الدوال كــ public في الclass وإن لم تفعل ذلك سخبركك المترجم بأن هنالك خطأ PHP كود : class A : ICالصحيح PHP كود : class A : ICيمكن لــ interface أن يرث من interface آخر PHP كود : interface IB : ICفي حال تعريف دالة داخل الــ interface سيكون لزاماً عليك استخدامها في الـ class التي يرث من الـ interface طيب ماذا لو كان لدينا class ورث من اثنين interface وكلا الـ interface يحتويان نفس الدالة حتى لو كانت الدوال لها وظائف مختلفة؟ بالشكل التالي: PHP كود : interface ICلذا يتم حل المشكلة بالشكل التالي: PHP كود : class A : IB, ICفي هذه الحالة الدوال تعرف على أنها private by default طيب كيف سيكون استدعاء الدوال؟ الجواب: سنستخدم هنا Explicit interface بالشكل التالي: لأن الدوال private فلا يمكن الوصول اليها إلا باستخدام Explicit interface PHP كود : private static void Main()تحياتي لكم RE: [مقال] متى استخدم الـ Interface ومتى استخدم الـ Class - الشاكي لله - 29-06-16 شكرا للاخ سجاد على المداخلة القيمة ، وشكرا للاخ امير الزبيدي على المشاركة والتشجيع يبدو ان مواضيع الـ OOP تعجبكم ![]() اذن اليوم مقالة اخرى ان شاء الله RE: [مقال] متى استخدم الـ Interface ومتى استخدم الـ Class - ابو ليلى - 30-06-16 انتظر..... حتى افرغ ما لدي بطريقة اخرى هذا النقاش اللذيذ كما اشار الاخ امير يعجبني وما دام الاخوة يقدمون الافضل و الاجمل لذا اصبح حق علي ان اشرح ما سبق بطريقتي و اتمنى ان تعجبكم الشرح استكمال لافكار كل الاخوة في المقال جزاهم الله كل خير و اثابهم الجنة. مع توسع قليل من قبلي اولا ان النوع abstract class يسمح بالتوريث من الكلاسات الاخرى (اي ترث منه الكلاسات الاخرى) ولا يمكنك انشاء نسخة مباشرة منه instantiated. ويجب الاشارة الى ان هذا النوع يجب ان يمتلك على الاقل واحدة او اكثر من الطرق المكتملة (اي تحتوي على كود ساسميه جسم الدالة) و كذلك على الاقل طريقة واحدة غير مكتملة اي بدون جسم للدالة , و يجب تعريفها بالمحدد abstract اذا كانت كل الطرق في الكلاس غير مكتملة عندها تصبح شبيهة بـ interface ثانيا الواجهات Interface يتم تعريفها بالكلمة المفتاحية interface و هي تحتوي على دوال غير مكتملة اي لاتحوي على جسم (تمهيد فقط) اما عن الفائدة منها فهو في الكلاس التي ستطبق و تستفيد من هذه الطرق بعد ان تكون قد ورثت interface السابقة و جميع الطرق و الخصائص داخل interface كما قال الاخ سجاد هي بشكل افتراضي عامة Puplic ساقوم بالشرح وفق الاكواد لتسهيل المهمة و لاعطاء الشرح هدف واضح طبعا انا ساكتب اكواد #C لان المقالة في هذا القسم بالتحديد (بالنسبة لاكواد #C انا اكتبها بحكم عملي على الجافا ) لننظر الى الكود التالي الذي يعرف كلاس بسيطة من النوع abstract Class PHP كود : public abstract class Productالكلاس بسيط يحتوي على حقلين مع خصائص لكل حقل ويحتوي على طريقة واحدة تعيد المجموع و لدي ايضا interface يحتوي على خاصيتين و نفس الدالة السابقة PHP كود : public interface Iproductوجه الخلاف اننا لا نستطيع تعريف متغيرات بشكل مباشر ضمن interface كما اشار الاخ الشاكي سابقا الان ساقوم بانشاء كلاس يقوم بتطبيق الواجهة Iproduct (سيتم تطبيق كل الخصائص و الطرق الموروثة هذا شرط اساسي) PHP كود : public class implementInterface: Iproductهل رايت كيف تم توسيع الطرق و الخصائص (هكذا تستفيد من اعادة التطبيق ) الان اريد التطبيق على الكلاس Product و هو من النوع abstract Class لدينا هنا كلاس جديد يقوم بوراثة الكلاس السابق Product و يعيد قيادة الطرق و الخصائص كما يلي PHP كود : public class implementAbstract: Productاصبح بامكاننا الاستفادة من هذا الكلاس في عملنا بشكل مباشر بعد ذلك يمكننا انشاء نسخة جديدة من الكلاس السابق implementAbstract و استخدمها في تطبيقنا كما يلي PHP كود : ImplementAbstract testAbstract = New implementAbstract();اماذا لو احببنا ان نستفيد من الكلاس implementInterface الذي قام بتطبيق الواجه Iproduct نعم يمكننا ذلك كم عملنا سابقا انظر الكود PHP كود : ImplementInterface testInterface = New implementInterface();بقي ان اقول لك بان الاعضاء المشتركة المعرفة بالطريقة (Static) لا يمكن وراثتها تحت اي ظرف كان لذا نحن لا نستطيع تعريفها داخل Interface . بينما يمكنك تعريف طرق مشتركة داخل الكلاسات من النوع abstract Class يمكننا اضافة الطريقة التالية الى الكلاس السابق Product PHP كود : public static void test()بينما لا يمكننا كتابتها في Interface اوجه الخلاف بين Abstract Class و Interfaces
بقي الحديث عن Sealed Class ليتضح معنى Sealed Class انظر معي لهذا الكلاس PHP كود : public sealed class classSealedلا يمكن اعتبار هذا النوع فئة قاعدية (Base Class) و ليست ايضا من النوع Abstract Class هي تستخدم تحديدا لمنع اعادة اشتقاقها و لانها ليست فئة قاعدية فان بعض معالجات النظام تستخدمها لتسريع عمليات الوصول الى الاعضاء بداخلها لا يمكنك اعادة اشتقاقها و ايضا لا يمكنك اعادة قيادة الطرق بداخلها و لا يمكنك وراثتها ايضا كيف يمكنني استخدامها اذاً , بكل بساطة انشأ نسخة منها و اسند القيم و استخدم الطرق بداخلها كما هي PHP كود : classSealed sc=new classSealed();بقي السؤال المطروح ايهما استخدم RE: [مقال] متى استخدم الـ Interface ومتى استخدم الـ Class - الشاكي لله - 30-06-16 كما قال اخونا "امير الزبيدي" هذا الموضوع لازم يتغير عنوانه لان هذي المعلومات لازم الكل يشوفها ويتعلم منها .. بالنسبة الى Sealed Class ابدا لم اتعامل معها
|