في الآونة الأخيرة، لدي بعض الخبرة في تعيين كائنات فئة فرعية لكائنات الفئة الأصلية، وأود أن أشاركها معك، لكن مستواي محدود، لذا يرجى تصحيحي وانتقادي.
وبالقرب من المنزل، إليك بعض الأمثلة الصغيرة، يرجى إلقاء نظرة عليها.
اختبار واحد
فئة الوالدين:
فئة فرعية:
النتيجة: هذه هي طريقة print() للفئة الأصلية - الكائن في هذا الوقت هو Subclass@126b249
في هذا الوقت الكائن هو Subclass@126b249
يوضح:
Supclass sub=new Subclass();
على الرغم من أن الكائن المُعلن هو كائن فئة أصل، إلا أن مساحة الذاكرة الفعلية تنتمي إلى كائن الفئة الفرعية.
يتم استدعاء الطريقة public void print() الموروثة من الفئة الأصلية، والإخراج هو دقة اسم كائن الفئة الفرعية.
الاستنتاج: الكائن المعلن في وقت الترجمة هو كائن فئة أصل، ولكنه في وقت التشغيل كائن فئة فرعية. إذا لم تتجاوز الفئة الفرعية طريقة الفئة الأصلية، فإن الكائن في هذا الوقت يستدعي الطريقة الموروثة من الفئة الأصلية.
اختبار 2
فئة الوالدين:
فئة فرعية:
النتيجة: هذه هي طريقة print() للفئة الفرعية - في هذا الوقت الكائن هو Subclass@126b249
في هذا الوقت الكائن هو Subclass@126b249
يوضح:
بناءً على المثال السابق، قمت بإعادة كتابة طريقة الطباعة () للفئة الأصلية، وفي هذا الوقت تم استدعاء طريقة الطباعة () للفئة الفرعية.
الاستنتاج: بناءً على استنتاج المثال السابق، توصلت إلى نتيجة: في هذا الوقت، يكون الكائن بالفعل كائن فئة فرعية عند التشغيل إذا لم تكتب الفئة الفرعية طريقة الفئة الأصلية.
ثم يستدعي الكائن في هذا الوقت الطريقة الموروثة من الفئة الأصلية؛ وإلا فإن الكائن في هذا الوقت يستدعي طريقة الفئة الفرعية.
سؤال: هل يمكننا استخلاص الاستنتاج التالي من الاختبار أعلاه: تعيين كائن الفئة الفرعية إلى كائن الفئة الأصل (أي Supclass sub=new Subclass())،
ما نحصل عليه هو كائن فئة فرعية، أي أن Su هو كائن فئة فرعية ؟؟؟؟؟؟
اختبار ثلاثة
فئة الوالدين:
فئة فرعية:
النتيجة: السمات في هذا الوقت: سمات الفئة الأصل
ملاحظة: بناءً على الاختبار الأول، قمت بإضافة className للسمة إلى الفئة الأصلية وتجاوزت هذه السمة في الفئة الفرعية.
ولكن عندما أقوم بإخراج خصائص الكائن في هذا الوقت، فهي خصائص الفئة الأصل.
الاستنتاج: عند تعيين كائنات فئة فرعية إلى كائنات فئة أصلية، تختلف الطرق والخصائص تمامًا عن علاقة الميراث التقليدية.
سؤال:
هل الكائن في هذا الوقت كائن فئة فرعية أم كائن فئة أصل؟
ابدأ بالتخمين:
هناك بعض النقاط التي يجب عليّ توضيحها قبل التكهن:
1. عندما نقوم بإنشاء كائن فئة فرعية جديد، يتم أيضًا تنفيذ مُنشئ كائن الفئة الأصل في نفس الوقت، أي أن بعض المعلومات الضرورية للفئة الأصلية وكائن الفئة الفرعية تشغل نفس مساحة الذاكرة.
عندما نتجاوز الطريقة، يمكننا استخدام الكائن الفائق للإشارة إلى الفئة الأصل.
2. الكائنات في Java ليست موجهة للكائنات بشكل كامل، أي أن سمات وأساليب الكائن لا يتم تغليفها في الكائن في نفس الوقت.
لكن الكائن له سماته الخاصة، لكن الطريقة تشير إلى الطريقة الموجودة في الفصل، ويمكن القول أنها تقوم بتغليف مراجع السمات والأساليب في الفصل في الكائن.
لذا فإن الطريقة التي يستدعيها الكائن ليست طريقته الخاصة، ولكنها طريقة موجودة في الفصل، لا أعرف لماذا تفعل Java ذلك.
3. عندما يتم تحميل الكائن في الذاكرة، يتم تحميل الفصل في الذاكرة أولاً، ثم يجب أن يبقى الفصل في الذاكرة، لا أعرف.
أعتقد أن جافا يجب أن يكون لديها آلية إعادة التدوير الخاصة بها، تمامًا مثل إعادة تدوير الأشياء.
4. التجميع والتشغيل شيئان مختلفان تمامًا، الأشياء الرئيسية التي تفعلها أثناء التجميع هي الإعلان عن نوع الكائن، وتعيين السمات، والتحقق من الأخطاء النحوية، وما إلى ذلك.
ما يفعله وقت التشغيل هو تحميل الكائنات في الذاكرة (عادةً ما يتم استخدام الانعكاس الجديد بشكل شائع)، وتشغيل وظائف تنفيذ التعليمات البرمجية، وما إلى ذلك.
5. إذا لم نتفق أنا وأنت، أيها القارئ، حول هذه النقاط، أو إذا لم يكن لدينا نفس الفهم حول هذه النقاط، فسوف تعتقد أنني أتحدث هراء.
ربما تعتقد أن درجة خبرتي منخفضة جدًا، وبالتالي فإن مصداقيتي منخفضة، لكن ما أريد قوله هو أنه لا يوجد ترتيب للتعلم، ومن يتقن يأتي أولاً.
هاها، أنا مستعد لتحويل نقاط خبرتي إلى قيم سلبية، لا مزيد من الهراء، فلنواصل.
المضاربة:
1. عندما نقوم بتجميع Supclass sub=new Subclass()، يتم الإعلان عن كائن sub كفئة Supclass، لذا فإن سمات كائن sub هي قيم سمات كائن الفئة الأصل.
3. استمرارًا من الخطوة 2، إذا قمنا بتجاوز طريقة الفئة الأصلية، نظرًا لأن مساحة ذاكرة كائن sub هي مساحة ذاكرة كائن فئة فرعية، فقد تم تحميل طريقة الفئة الفرعية public void print() في الذاكرة.
إذن ما نسميه هو الطريقة public void print() للفئة الفرعية. إذا كنت بحاجة إلى استدعاء الطريقة المتجاوزة للفئة الأصلية، فأنت بحاجة إلى استخدام super.
هذا المقطع يمكن أن يشرح الاختبار 2.
تلخيص:
وفيما يلي آراء شخصية بحتة:
قم بتعيين كائن فئة فرعية إلى كائن الفئة الأصل، والكائن الناتج هو كائن مثل هذا:
يتم تجميعه ككائن فئة أصل، ولكن يتم تشغيله ككائن فئة فرعية، والخصائص المحددة هي كما يلي.
1. تم الإعلان عنه ككائن فئة أصل 2. له سمات فئة أصل 3. يشغل مساحة الذاكرة الخاصة بالفئة الفرعية 4. عندما تتجاوز طريقة الفئة الفرعية طريقة الفئة الأصلية، يستدعي الكائن طريقة الفئة الفرعية في هذا الوقت، وإلا يتم الميراث تلقائيًا تسمى أساليب الفئة الأصل.
5. أعتقد أن هذا الكائن ليس كائنًا من الفئة الأصلية ولا كائنًا من الفئة الفرعية.
أنا أعامله ككائن فئة فرعية؛ إذا استخدمت خصائصه، فأنا أعامله ككائن فئة أصل.
إنه كائن يحتل سمات الفئة الأصلية ويستخدم أساليب الفئة الفرعية. أما بالنسبة لنوع الكائن، فأعتقد أنه يعتمد على الإعلان، ويجب اعتباره كائنًا من الفئة الأصلية، ولكنه يحتوي على فئة فرعية طُرق.
فكر في الأمر:
بناء على الاختبار 3، كيف يمكننا استخراج سمات الفئة الفرعية؟ ؟ ؟ ؟ ؟