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

تلبيس او قولبة كائن جافا

عملية التلبيس أو القولبة Typecast or typecasting:


تحويل النوع في مجال برمجة الكمبيوتر، هو عملية أو نتيجة لتغيير نوعية البيانات لكيان من نوعية إلى نوعية أخرى ، و بمعنى اخر تغيير نوع البيانات من نوع إلي نوع اخر في وقت التحويل البرمجي بدون التقييد بنوع معين وبدون التغيير في قيمتها إلا في حالات معينة فقط.
في عملية تلبيس او قولبة كائن جافا (typecasting) يمكن لمرجع كائن ان يتم تلبيسه او قولبته  في مرجع كائن آخر.
التلبيس او القولبة يمكن أن تكون  للفئة نفسها  أولأحد الفئات الفرعية، أو الفئة المتفوقة أو الواجهات.
يوجد قواعد لوقت التحويل البرمجي "compile-time"  و قواعد لوقت التشغيل "runtime"  لعملية التلبيس او القولبة "casting"  في جافا.


كيف نقوم بتلبيس او بمعنى آخر قولبة كائنات بواسطة فئة ديناميكيا تم تحميلها؟


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

يمكن أن يكون هناك اثنين من سيناريوهات جافا للقولبة 

  • Upcasting   آب كاستينق
  • Downcasting   داون كاستينق

عندما نقولب مرجع على امتداد التسلسل الهرمي انطلاقا من  الطبقة الجذرية في اتجاه أحد الفئات الفرعية، يسمى داونكاست. عندما نقولب مرجع على امتداد التسلسل الهرمي انطلاقا من أحد الفئات الفرعية  في اتجاه الطبقة الجذرية ، يسمى آبكاست. لا نحتاج إلى استخدام مشغل القولبة في هذه الحالة.

قواعد وقت التحويل البرمجي "compile-time"  موجودة لإلتقاط محاولات القولبة في الحالات الغير ممكنة. يحدث هذا عندما نحاول قولبة الكائنات الغير مترابطة تماما (وهذه ليست علاقات لفئة  فرعية أو لفئة  من الدرجة الاولى أو لواجهة). عند وقت التشغيل يتم طرح ClassCastException  إذا كان الكائن الذي سيتم قولبته غير متوافق مع النوع الجديد الذي سيتم القولبة إليه.

أدناه هو مثال يظهر متى يمكن حدوث ClassCastException  أثناء قولبة  الكائن "object casting"



قولبة مراجع الكائن "Object References": قولبة ضمنية باستخدام المحول البرمجي "Compiler" 


بشكل عام القولبة الضمنية تتم عندما يتم تعيين مرجع كائن "Object reference" (قولب أو تلبيس) إلى :

  • مرجع المتغير "reference variable" الذي لهو نفس نوع الفئة التي تم إنشاء الكائن منها.
  • الكائن كفئة كائن "Object  Class" هي الفئة الفائقة "super class" لكل فئة.
  • مرجع المتغير "reference variable" من نوع الفئة الفائقة "super class" للفئة  التي تم إنشاء الكائن منها.
  • مرجع المتغير "reference variable" من نوع واجهة  "interface"  التي تم تنفيذها "implemented"  من قبل الفئة  التي تم إنشاء الكائن منها.
  • مرجع المتغير "reference variable" من نوع واجهة  "interface"  التي تم تنفيذها "implemented"  من قبل الفئة الفائقة "super class" للفئة  التي تم إنشاء الكائن منها.

ليكن لدينا  واجهة "interface" إسمها وسيلة نقل "Vehicle"، و فئة فائقة "super class" إسمها  سيارة "Car"  و لها فئة فرعية "subclass" إسمها فورد "Ford". المثال التالي يوضح التحويل التلقائي من المراجع الكائن "object references" التي تمت معالجتها بواسطة المحول البرمجي "compiler"




ليكن "c" متغير من فئة السيارة "Car" و "f" من فئة  فورد "Ford" و "v" تكون مرجع الواجهة وسيلة نقل "vehicle ". يمكننا تعيين المرجع  "Ford" للمتغير "Car" :

مثال رقم 1








المحول البرمجي يعالج تلقائيا عملية التحويل و بما ان الأنواع متوافقة ( علاقة  بين فئة فرعية "subclass" و فئة فائقة "super class" ) ، أي نوع "Car" يمكن أن يشتمل  نوع "Ford" بما ان "Ford" هي سيارة "Car".


مثال رقم 2


التحويل الغير مشروع من النوع واجهة "interface type" إلى النوع فئة "class type"  سوف ينتج خطأ في عملية التحويل البرمجي و "v"هو مرجع  الواجهة "Vehicle v"
المحول البرمجي يعالج تلقائيا عملية التحويل و بما ان الأنواع متوافقة ( علاقة  بين فئة "class" و واجهة "interface" ) ، أي نوع "Car" يمكن أن يقولب "cast to" لنوع "Vehicle interface" بما ان "Car" هي  تنفيذ " implements" لــ "Vehicle Interface" (السيارة هي وسيلة نقل).

قولبة مراجع الكائن : القولبة الواضحة



أحيانا نقوم بقولبة واضحة "explicit cast" في جافا عندما تكون القولبة الضمنيا "implicit casts" لا تعمل أو ليست مفيدة لسيناريو معين. القولبة الواضحة "explicit cast" ليست سوى اسم النوع الجديد الموجود بين قوسين. مثل ما كان في السابق، بالنسة لفئة "Car" و الفئة "Ford"





كما ان لدينا الوظيفة  breakingSystem () الذي يأخذ المرجع "Car" (مرجع الفئة الفائقة "Superclass reference" ) كقيمة وسيطة للمدخلات "input parameter".
فإن المنهج يستدعي  carMethod () بغض النظر عن نوع الكائن (مرجع "Car" أو مرجع "Ford") وإذا كان هو كائن "Ford"، فإنه سيتم أيضا استدعاء fordMethod (). نستخدم المشغل instanceof لتحديد نوع الكائن في وقت التشغيل.


لإستدعاء fordMethod ()، العملية "(Ford) obj " تخبر المحول البرمجي "compiler" لعلاج الكائن المشار إليه بواسطة "obj"  كما لو أنه كائن "Ford". بدون القولبة فإن  المحول البرمجي "compiler" سوف يعطي رسالة خطأ تشير إلى أنه لا يمكن العثور  على fordMethod ()  في تعريف "Car".
يقدم البرنامج التالي توضيح استخدام مشغل القولبة "cast operator" مع المراجع.
ملاحظة : الفئات "Honda" و "Ford" يعتبروا أشقاء في التسلسل الهرمي للفئة. كل من الفئاتين هي فئة فرعية  "subclasse"من فئة "Car". كل من الفئة "Car" و الفئة "HeavyVehicle" إمتداد لفئة كائن "Object Class".
فإن أي فئة التي لا تمتد بشكل واضح من بعض فئات أخرى تمتد تلقائيا من كائن "object" افتراضيا. هذا الرمز ينشئ كائن مثيل لفئة "Ford"  ويقوم بتعيين مرجع الكائن لمرجع المتغير من نوع "Car".
ويسمح لهذا التعيين على اساس ان "Car" هي الفئة المتفوقة "superclass" لــ "Ford". من أجل استخدام مرجع من نوع فئة لاستدعاء المنهج "method"، يجب تعريف  المنهج "method" عند أو أعلى من هذه الفئة  في التسلسل الفئة الهرمي.
وبالتالي لا يمكن لكائن من فئة "Car" إستدعاء المنهج "method" موجودة في الفئة "Class Ford" ،  حيث أن المنهج  fordMethod غير موجود في الفئة "Car" أو اي واحد من الفئة المتفوقة "superclass" لها.
ويمكن بالتالي أن تحل هذه المشكلة بواسطة دونكاسة "downcast" بسيط  عن طريق قولبة مرجع الكائن  "Car" الى مرجع الفئة "Ford" كما فعلنا في البرنامج.
أيضا محاولة قولبة مرجع كائن الى مرجع الكائن الشقيق له تنتج ClassCastException في وقت التشغيل، على الرغم من ان عملية التحويل البرمجي تحدث من دون أي خطأ.





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



Output
Username : asdf
Username : asdf
Password : qwer



عامل التشغيل "instanceof" 


عامل التشغيل "instanceof" يسمى بمشغل مقارنة النوع ، يتيح لك تحديد ما إذا كان كائن ينتمي إلى فئة معينة، أو تنفيذ لواجهة معينة. فإنها تعود بصحيح "true" إذا كان الكائن هو مثيل لفئة "instance of the class" أو إذا كان الكائن تنفيذ لواجهة "implements the interface"، وإلا فإنها تعود بــ false.

أدناه هو مثال يوضح استخدام المشغل instanceof



Output
hV is an HeavyVehicle: true
T is an HeavyVehicle: true
hV is a Truck: false
hv2 is an HeavyVehicle: false



ملاحظة : hv2  ليس له مرجعية الى حد الان لكائن "HeavyVehicle" و ترجع instanceof  بــ false. كما أننا لا نستطيع استخدام المشغل instanceof مع الفئات الأشقاء.

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

إرسال تعليق