اكتب تحويل الكائنات متعددة الأشكال Java <br /> يشير تحويل نوع الكائن المذكور هنا إلى كائن له علاقة ميراث ، وليس كائنًا من أي نوع. عند إلقاء كائن ليس له علاقة ميراث ، يلقي وقت تشغيل Java استثناء java.lang.classcastexception.
في سلسلة الميراث ، نسمي تحويل الفئة الفرعية إلى فئة الوالدين "التحول الأعلى" وتحويل الفئة الأم إلى فئة الطفل "التحول الهبوطي".
في كثير من الأحيان ، نحدد المتغيرات كنوع من فئة الأصل ولكن نشير إلى كائن فئة الطفل. عند تشغيل البرنامج ، يستخدم الربط الديناميكي لتحقيق الدعوة إلى أساليب الفئة الفرعية ، أي تعدد الأشكال.
ومع ذلك ، في بعض الأحيان من أجل إكمال الوظائف التي لا تملكها بعض فئات الوالدين ، نحتاج إلى تحويل كائنات الفئة الفرعية التي تحولت إلى تصاعدي إلى فئات فرعية واتصال بطرق الفئة الفرعية ، والتي هي التحول الهبوطي.
ملاحظة: لا يمكن إلقاء كائن الفئة الأصل بشكل مباشر على نوع الفئة الفرعية ، ويمكن تحويل كائن الفئة الفرعية بعد التحول التصاعدي إلا إلى نوع فئة فرعية مرة أخرى. بمعنى آخر ، يجب تحويل كائنات الفئة الفرعية إلى الأعلى قبل أن تتمكن من التحول لأسفل. يرجى الاطلاع على الرمز التالي:
الطبقة العامة التجريبية {public static void Main (String Args []) كائن الوالدين.قم بإزالة التعليق على السطر 7 ، وسيتم طرح استثناء في وقت التشغيل ، ولكن يمكن تمرير التجميع.
نظرًا لوجود مخاطر في الانتقال إلى الأسفل ، عند تلقي مرجع إلى فئة الوالدين ، تأكد من استخدام عامل التشغيل لتحديد ما إذا كان الكائن هو الفئة الفرعية التي تريدها.
الطبقة العامة التجريبية {public static void main (string args [] = (Sonclass) superobj ؛ ) superobj ؛ نتائج التشغيل:
① لا يمكن تحويل
ملخص: يتم فحص نوع الكائن عند تشغيل البرنامج.
تعدد الأشكال Java والربط الديناميكي <BR /> في Java ، يمكن أن تشير متغيرات الفئة الأصل إلى مثيلات فئة الأصل أو مثيلات فئة الطفل.
يرجى قراءة قطعة من الرمز أولاً:
الطبقة العامة {public static void (args) .Cry () ؛ Call of Cat public void cry () {system.out.println ("meow ~") ؛ }} نتائج التشغيل:
لا أعرف كيف أتصل بالمواء ~ الصوف ~
يعرّف الكود أعلاه ثلاث فئات ، وهي فصول القط والكلاب. يحتوي متغير OBJ على نوع الحيوان ، والذي يمكن أن يشير إلى مثيلات من فئة الحيوانات ، وكذلك مثيلات من فصول القط والكلاب ، وهو أمر صحيح. أي أن متغيرات الفئة الأصل يمكن أن تشير إلى مثيلات فئة الأصل أو مثيلات فئة الطفل. لاحظ أن العكس هو الخطأ ، لأن جميع القطط حيوانات ، ولكن ليس كل الحيوانات قطط.
يمكن أن نرى أن OBJ يمكن أن يكون الإنسان أو القطة أو الكلب. يشير تعدد الأشكال إلى شيء له أشكال أو أشكال مختلفة.
على سبيل المثال ، "البشر" لديهم العديد من التعبيرات أو التطبيقات المختلفة. ، أو المعلم ، أو الطبيب في الحياة القادمة.
هناك ثلاثة شروط ضرورية لوجود تعدد الأشكال: تشير الميراث ، إعادة الكتابة ، والمتغيرات الأم إلى كائنات الفئة الفرعية.
عند استدعاء طريقة باستخدام طريقة متعددة الأشكال:
تحقق أولاً ما إذا كانت الطريقة موجودة في الفئة الأصل.
إذا تجاوزت الفئة الفرعية الطريقة ، يتم استدعاء طريقة الفئة الفرعية ، وإلا فإن طريقة الفئة الأصل تسمى.
من المثال أعلاه ، يمكننا أن نرى أن ميزة تعدد الأشكال هي أنه عندما يكون هناك العديد من الفئات الفرعية ، لا توجد حاجة لتحديد متغيرات متعددة. يرجى إلقاء نظرة على المثال التالي:
Demo Public Class {public static void main (string [] args) {// بمساعدة تعدد الأشكال ، يمكن للمالك إطعام العديد من الحيوانات MA = New Master () ؛ ) ؛ ) {system.out.println ("أنا حيوان صغير ، الأكل" + f.getfood ()) ؛ قطة صغيرة تتناول الطعام " + f.getfood ()) ؛}} يمتد كلب الفئة الحيوان {public void eat (food f) {system.out.println (" أنا كلب ، الأكل " + f. getfood ()) ؛ String getFood () {Return "Bone" ؛ نتائج التشغيل:
أنا حيوان صغير ، آكل الأشياء ، أنا قطة صغيرة ، آكل السمك ، أنا كلب ، وأكل العظام
تحتوي طريقة التغذية للفئة الرئيسية على معلمتين ، وهما نوع الحيوان ونوع الطعام. حيوانات مختلفة.
الربط الديناميكي
من أجل فهم طبيعة تعدد الأشكال ، دعونا نتحدث عن العملية التفصيلية لطرق الاتصال Java أدناه.
1) يتحقق المترجم من نوع الإعلان واسم طريقة الكائن.
لنفترض أن OBJ.func (param) يسمى ، OBJ هو كائن من فئة CAT. تجدر الإشارة إلى أنه قد يكون هناك طرق متعددة بأسماء مع FUNC ولكن معلمات مختلفة. على سبيل المثال ، قد توجد طرق FUNC (int) و func (سلسلة). ستقوم برنامج التحويل البرمجي بإدراج جميع الطرق المسمى FUNC في فئة CAT والأساليب التي تصل إلى السمة العامة و NABOR FUNC في Animal Parent Class.
وبهذه الطريقة ، يحصل المترجم على قائمة بجميع أساليب المرشحين الممكنة التي يجب استدعاؤها.
2) بعد ذلك ، سيقوم المحرر بالتحقق من توقيع المعلمة المقدمة عند استدعاء الطريقة.
إذا كانت هناك طريقة في جميع الطرق المسمى FUNC تتوافق تمامًا مع توقيع المعلمة المقدمة ، فحدد هذه الطريقة. هذه العملية تسمى دقة التحميل الزائد. على سبيل المثال ، إذا تم استدعاء FUNC ("Hello") ، فسيتم اختيار برنامج التحويل البرمجي FUNC (سلسلة) بدلاً من FUNC (int). نظرًا لوجود تحويل النوع التلقائي ، على سبيل المثال ، يمكن تحويل INT إلى مضاعفة. نهاية أو طرق متعددة تطابقها ، ثم تجميع الخطأ.
وبهذه الطريقة ، يحصل المترجم على اسم الطريقة وتوقيع المعلمة التي يجب استدعاؤها.
3) إذا كان معدّل الأسلوب خاصًا ، ثابتًا ، نهائيًا (سيتم شرحه في وقت لاحق) ، أو مُنشئ ، فسيكون المترجم قادرًا على معرفة الطريقة التي يجب استدعاؤها بالضبط. .
في المقابل ، تعتمد الطريقة المدعوين على النوع الفعلي للكائن وتنفيذ الربط الديناميكي في وقت التشغيل. على سبيل المثال ، عند الاتصال بـ FUNC ("Hello") ، سيستخدم المحرر الربط الديناميكي لإنشاء توجيه يدعو FUNC (سلسلة).
4) عندما يقوم البرنامج بتشغيل ويستخدم الربط الديناميكي لاستدعاء الطريقة ، فإن JVM سوف يستدعي بالتأكيد طريقة الفئة الأكثر ملاءمة للنوع الفعلي للكائن المشار إليه بواسطة OBJ. لقد افترضنا أن نوع OBJ الفعلي هو CAT ، وهو فئة فرعية للحيوان ، ويسمى إذا تم تعريف FUNC (سلسلة) في CAT ، وإلا سيتم البحث في فئة الحيوانات وفئة الأم.
تتطلب كل مكالمة إلى هذه البحث ، وهو أمر مكلف للغاية. وبهذه الطريقة ، عندما يتم استدعاء الطريقة فعليًا ، يمكن للجهاز الظاهري البحث عن هذا الجدول فقط. في المثال أعلاه ، يبحث JVM في جدول طريقة فئة CAT للعثور على طريقة تتطابق مع المكالمة مع FUNC ("Hello"). قد تكون هذه الطريقة إما cat.func (سلسلة) أو Animal.func (سلسلة). لاحظ أنه إذا تم استدعاء Super.func ("Hello") ، فسيقوم برنامج التحويل البرمجي بالبحث في جدول طريقة الفئة الأصل.
على افتراض أن فئة الحيوانات تحتوي على ثلاث طرق: Cry () ، getName () ، و getage () ، فإن جدول الطريقة الخاص به هو كما يلي:
Cry () -> Animal.cry ()
getName () -> Animal.getName ()
getage () -> animal.getage ()
في الواقع ، لدى Animal أيضًا كائن فئة Parent افتراضي (والذي سيتم شرحه لاحقًا) ، والذي سيرث طريقة الكائن ، وبالتالي فإن الأساليب المذكورة أعلاه غير مكتملة.
على افتراض أن فئة CAT تتجاوز طريقة Cry () في فئة الحيوانات وتضيف طريقة جديدة Climbtree () ، فإن قائمة المعلمات الخاصة بها هي:
Cry () -> cat.cry ()
getName () -> Animal.getName ()
getage () -> animal.getage ()
Climbtree () -> cat.climbtree ()
عند التشغيل ، تكون عملية استدعاء طريقة OBJ.Cry () كما يلي:
يصل JVM أولاً إلى جدول الطريقة للنوع الفعلي لـ OBJ ، والذي قد يكون جدول طريقة فئة الحيوان ، أو جدول طريقة فئة CAT والفئات الفرعية.
يبحث JVM عن طريقة مطابقة Cry () في جدول الطريقة ، وبعد العثور عليها ، ستعرف الفئة التي تنتمي إليها.
يدعو JVM هذه الطريقة.