الأربعاء، 17 أكتوبر 2012

الفئة المجردة و الواجهة لجافا

الفئة المجردة لجافا  Abstract Class in java  

تستخدم الفئات المجردة لجافا "Java Abstract classes" للإعلان عن الخصائص المشتركة للفئات الفرعية "subclasses". الفئة المجردة لا يمكن أن تكون فئة مثيل "Instance". لا يمكن استخدامها إلا بوصفها الفئة المتفوقة "superclass" للفئات الأخرى الاتي إمتددن من الفئة المجردة. يتم تعريف الفئات المجردة بالكلمة المجردة "abstract keyword". وتستخدم الفئات المجردة لتوفير قالب أو تصميم لفئات فرعية محددة أسفل شجرة الميراث "inheritance tree".


مثل أي فئة أخرى، يمكن لفئة مجردة أن تحتوي على حقول التي تصف الخصائص والأساليب التي تصف الإجراءات التي يمكن أن تؤديها الفئة. يمكن لفئة مجردة "abstract class" أن تشمل المناهج التي لا تحتوي على التنفيذ "implementation". وتسمى هذه بالمناهج التجريدية "abstract methods". يجب الإعلان نهاية  المنهج التجريدي بفاصلة منقوطة ";" "semicolon" بدلا من كتلة. إذا كانت الفئة  لديها أي منهج  مجرد "abstract methods"، سواء المعلنة أو الموروثة، فيجب أن تعلن الفئة كاملة كفئة مجردة. و تستخدم المناهج التجريدية "abstract methods" لتقديم نموذج للفئات التي ترث المنهج  المجرد "abstract methods".
لا يمكن أن يكون للفئات المجردة مثيل، ويجب أن يكونوا كفئات فرعية ، ويجب توفير التطبيقات الفعلية للمناهج التجريدية "abstract methods". و بطبيعة الحال يمكن ان يتم تجاوز أي تنفيذ محدد، من قبل فئات فرعية إضافية "subclasses". يجب أن يكون للكائن تنفيذ لجميع مناهجه. تحتاج إلى إنشاء فئة فرعية لتوفر تنفيذ للمنهج التجريدي "abstract method".

ويمكن لفئة مجردة تسمى بــ "Vehicle"  ان يتم تحديدها مجردة لتمثيل التجريد العام لوسيلة نقل "Vehicle"،كما ان خلق  مثيلات "instances" من الفئة لا يكون ذا مغزى.

مثال على فئة تسمى شكل "shape" تعتبر كفئة مجردة
يمكننا أيضا تنفيذ الفئة أشكال عامة "shapes" كفئة مجردة حتى نتمكن من رسم خطوط ودوائر ومثلثات الخ ، جميع الأشكال لها بعض الحقول المشتركة و المناهج ، ولكن لكل واحد منها ، بطبيعة الحال ،المزيد من الحقول و المناهج. الفئة مجردة تضمن بأن يكون لكل شكل نفس الخصائص الأساسية. ونقوم بإعلان هذه الفئة مجردة لأنه لا يوجد شيء يمثل شكل عام. يمكن أن يكون هناك فقط الأشكال الملموسة مثل مربعات مثلثات ودوائر الخ




Output 
point: 0, 0

لاحظ أنه ، من أجل إنشاء كائن نقطة "Point" ، ففئتها لا يمكن أن تكون مجردة. هذا يعني أن كل المناهج المجردة للفئة شكل "Shape" يجب أن تنفذ من قبل الفئة نقطة "Point".


يجب أن تُعرِف الفئة الفرعية التنفيذ لكل منهج تجريدي "abstract method" للفئة المتفوقة المجردة ، أو الفئة الفرعية نفسها سوف تكون أيضا مجردة. وبالمثل يمكن أن يتم إنشاء كائنات أخرى باستخدام الشكل العام للفئة التجريدية.
العيب الكبير في استخدام الفئات المجردة هو عدم الفدرة على استخدام وراثة متعددة. بمعنى، عندما تمتد فئة من فئة مجردة، فإنه لا يمكنها تمديد أية فئة أخرى.

واجهة جافا Java Interface

في جافا، يتم حل مشكلة الوراثة "inheritance" المتعددة بإستعمال بناء قوي يسمى الواجهات "interfaces". ويمكن استخدام واجهة لتحديد القالب العام "generic template" ومن ثم فئة مجردة أو أكثر لتحديد  التطبيقات جزئية للواجهة. الواجهات تحدد فقط  الإعلان عن المنهج "method" (العام  و الضمني  و المجردة "implicitly public and abstract")، ويمكن أن تحتوي فقط على الحقول (التي هي ضمنية  ، العامة ، نهائية ، ثابتة "implicitly public static final"). تعريف الواجهة يبدأ مع  الكلمة الرئيسية واجهة "interface".  واجهة  لفئة مجردة مثل هذه لا يمكن إنشاء مثيل لها "instantiated".

الوراثة المتعددة "Multiple Inheritance" يسمح بها عند تمديد  الواجهات. واجهة واحدة يمكن أن تمتد الى واجهة  أو أكثر. جافا لا تدعم الوراثة متعددة "Multiple Inheritance" ، ولكنها تسمح لك بتمديد "extend" فئة واحدة وتنفيذ العديد من الواجهات.

إذا كانت الفئة التي تُطبق الواجهة لا تُعَرِّفْ جميع المناهج للواجهة، فيجب أن يتم إعلانها مجردة و تعريفات المناهج يجب ان توفيرها الفئة فرعية الاتي يمتددن من الفئة مجردة.

المثال 1 : فيما يلي مثال لواجهة بإسم شكل "interface"


يوجد أدناه الفئة نقطة "Point class" التي تطبق الواجهة الشكل "Shape interface".




على نحو مماثل، يمكن إنشاء الكائنات شكل الأخرى بإستعمال واجهة برمجة "interface programming" عن طريق تنفيذ واجهة شكل عامة .

مثال 2 : وفيما يلي برنامج لواجهات جافا "java interfaces program" يعرض قوة برمجة الواجهة "interface programming" لجافا

القائمة أدناه تضهر لنا 2 من الواجهات و 4 فئات  واحدة منهم فئة مجردة.
ملاحظة : المنهج toString في الفئة A1 هو نسخة تجاوزناها للمنهج الذي تم تحديده في فئة تسمى كائن "Object". الفئات B1 و C1 تلبي متطلبات عقد الواجهة. ولكن بما أن الفئة D1 لا  تقوم بتعريف كافة المناهج لتطبيق الواجهة I2 ، فإن الفئة D1  أعلنت مجردة.

أيضا ،
تُنتج "i1.methodI2" خطأ في عملية التحويل البرمجي "compilation" لأن هذا المنهج لم يعلن في I1 أو أي واحدة من الواجهات الفائقة لها هذا إذا كانت موجودة. بالتالي المسبل او ما يسمى بالداونكسة "downcast" لمرجعية الواجهة I1 يحل المشكلة كما تظهر في البرنامج. المشكلة نفسها تنطبق على "i1.methodA1" ، و تحل ايضا عن طريق المسبل او ما يسمى بالداونكسة "downcast".

عندما نستدعي المنهج toString () الذي هو منهج للفئة كائن "Object"، لا يبدو أن هناك أي مشكلة باعتبار أن كل واجهة أو فئة تمتد من كائن "Object" و أي فئة يمكن ان تتجاوز toString () الافتراضي لتتناسب مع احتياجات التطبيق الخاص بك. ((C1) O1). methodI1 () لها تحويل برمجي ناجح ، ولكن يُنْتِجْ ClassCastException في وقت التشغيل "runtime". هذا لأن B1 ليس لديها أي علاقة مع C1 إلا أنهم "الأشقاء". لا يمكنك قولبة الأشقاء واحدا في الآخر.

عندما يتم استدعاء منهج واجهة معينة على مرجع معين ، السلوك الذي سوف ينتج سيكون مناسب للفئة التي منها تم إنشاء هذا الكائن المعينة. هذا هو  تعدد أشكال وقت التشغيل "runtime polymorphism" استنادا إلى الواجهات و هيمنة المناهج.




Output 

I am in methodI1 of class B1

I am in methodI2 of class B1

I am in methodI1 of class B1

I am in methodI2 of class B1

var2 : I am in methodA1 of class A1
var3 : I am in methodA1 of class A1
var4 : toString() method of class A1
var5 : toString() method of class A1
var6 : C1@190d11
I am in methodI1 of class B1
I am in methodI1 of class B1
I am in methodI1 of class B1

ليست هناك تعليقات:

إرسال تعليق