سؤال

حصلت على ما يلي:

class A{  
    int foo;  
}  
class B extends A{  
    public void bar();  
}

حصلت على مثيل من A وأريد تحويله إلى مثيل B دون فقدان الإشارة إلى FOO المتغير.

فمثلا:

A a = new A();  
a.foo = 2;  
B b = a; <-- what I want to do.  
//use b  
b.foo = 3;  
//a.foo should now be 3

شكرا على اي مساعدة!

هل كانت مفيدة؟

المحلول

جافا لا تدعم هذا. يمكنك الاستفادة من تعدد الأشكال لعلاج مثيل B كما ومثال من A ولكن ليس العكس.

السبب في أنك لا تستطيع القيام بذلك هو أنه لا توجد طريقة آمنة من النوع لضمان أن مثيلك A هو في الواقع مثال على B (يمكنك إلقاء المثيل ، لكن حتى لو فعلت ذلك ، فستضمن نفسك استثناءًا فقط في وقت التنفيذ).

أفضل طريقة لمعرفة ما إذا كانت هناك علاقة متعددة الأشكال بين الأنواع هي اختبار هذا البيان للصلاحية:

أي مثيل من نوع ما هو مثيل لنوع آخر.

على سبيل المثال:

أي مثيل للكلب هو مثال الثدييات.
أي مثال من الثدييات هو مثال للكلب.

لاحظ أن المثال الأول صحيح في حين أن الثانية خاطئة. ما تحاول القيام به في مثال الكود الخاص بك هو بالضبط محاولة التعامل مع أي ثدييات ككلب - على الرغم من أنه قد يكون صحيحًا أحيانًا ، فهو ليس صحيحًا بشكل قاطع مما يعني أن المترجم لن يسمح بذلك.

مرة أخرى ، للأوقات التي يمكن أن يكون فيها صحيحًا ، يجب عليك إلقاء المرجع ولكن هذا يفتح لك الاستثناءات في وقت التنفيذ. مثالك المحدد أعلاه هو أحد تلك الأوقات التي يحدث فيها استثناء حيث يمكننا أن نرى بوضوح أنك قد قمت بتثبيت مثيل من النوع A.

نصائح أخرى

استخدم منشئ النسخ:

class B extends A{  
    public B(A a){
        this.foo = a.foo;
    }
}

لا يمكنك فعل ذلك بوضوح لأن نوع وقت التشغيل للمتغير a سيكون على أي حال A, ، ليس B.

هذا يعني ذاك a لن يكون لها خصائص B.. ولا يمكنك الحصول عليها مع فريق الممثلين!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top