سؤال

في جاوة، لنفترض أن لدي 3 فئات، C تمتد من B التي تمتد من A.

class X {
   interface A {}
   interface B extends A {}
   interface C extends B {}
   void f(A a) {}

   void test() {
      C c = new C()
      B b = (B) c;

      f(b);
   }
}

إذا أفعل شيئا من هذا القبيل كما هو مبين في test() أعلاه:

C c = new C()
B b = (B) c;

f(b);

وf() يقبل b كنوع C منذ C وB كلا تمتد من A. أردت f() لتلقي b كنوع B ولم تكتب C.

وهناك على أية حال لفرض هذا upcasting؟

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

المحلول

وf() سوف <م> دائما الحصول على شيء كتبته كما ألف (على الرغم من تحت الأغطية انها فعلا B أو C، ويمكن مسبل بشكل مناسب).

ويمكنك تعريف و إضافية () وهكذا

f(B b);

وإذا لزم الأمر

f(C c);

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

لاحظ أن يلقي بك في السؤال لا لزوم لها. يمكنك كتابة:

C c = new C()
B b = c;

f(b);

ومنذ C تمتد من B، C <م> هو B.

نصائح أخرى

ويبدو أنك الخلط حول الفرق بين نوع ونوع وقت الترجمة وقت التشغيل.

وإنك لعلى خلق كائن (أشار إليها من قبل المراجع ج و ب) من نوع C، وسوف أنه البقاء وC، لأنه من المستحيل تغيير وقت التشغيل نوع الكائن، وبالتالي السلوك. قبل الصب يمكنك فقط تغيير نوع وقت الترجمة، والذي يؤثر على كيفية المترجم يعامل ذلك.

ويمكنك ان تعطي بعض مزيد من المعلومات حول مشكلة محددة تحاول حل؟ على الأرجح هناك وسيلة لتحقيق الهدف الخاص بك عن طريق تغيير التصميم.

<اقتباس فقرة>   

وأردت و لتلقي ب كنوع B و C. لا اكتب

وA C هو B هو A.

ومن داخل f، f يرى سوى جزء A من a به المعلمة إذا طلب f وظيفة A الجمهور الذي تجاوز في C، ويسمى تجاوز C.

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

إذا يجب أن يكون "C" و "B" نفس السلوك، لا ovveride أن السلوك في C.

وماذا تريد أن تفعل هذا؟

وسؤالك لا معنى له. ماذا تقصد ب "و تقبل ب كنوع C"؟

و تقبل ب كنوع A، منذ توقيع الأسلوب يقول "A". إذا قمت باستدعاء الأساليب على ب، سيتم استدعاء على C لو C يتجاوز لهم. ولكن هذا هو السلوك القياسية في جاوة (جميع الأساليب هي أساليب مثل الظاهرية في C ++)، وليس هناك وسيلة لتغيير ذلك.

وربما يمكنك وصف المشكلة الفعلية الخاصة بك، ثم أننا قد تكون قادرة على مساعدة.

والحقيقة أنه يمكنك تمرير أي فئة فرعية من A كمعلمة و (A أ) هو الأصيل في OO في جاوة، وليس هناك طريقة يمكن أن تذهب نحو هذا. إذا C تمتد A، يمكنك <م> دائما استخدامه حيث من المتوقع وA.

ويمكنك استخدام انعكاس للتحقق مما إذا كانت المعلمة هي من الدرجة A:

public void f(A a) {
  if (a.getClass() == A.class) {
    // ok, go on
  }
  else {
    System.err.println("The parameter is not of class A!");
  }
}

لا أعرف اذا كان هذا ما تريد، ولكن قد يكون من المفيد.

ويمكن أن تحل مشكلتك من خلال فهم الفرق بين نوع الإشارة ونوع المثال. عند يلقي لك C الاعتراض أ ب، يمكنك فقط تغيير نوع إشارة - على سبيل المثال الفعلي للكائن لا يزال الكائن C - وهذا ينبغي أن يكون واضحا تماما اذا نظرتم الى وجوه الخاص بك في وضع التصحيح. تغيير التأثيرات الوحيدة نوع مرجع كيفية معالجة مترجم / ترى رمز - لا ينبغي أن تتأثر سلوك وقت التشغيل. فإن أي استدعاء الأسلوب على كائن C يتذرع دائما طريقة C من (بغض النظر عما إذا تم أو لم يتم محمل الكائن إلى شيء آخر). إذا كنت overode أسلوب من B وترغب في استدعاء النسخة B من طريقة، فإنك سوف تحتاج إلى إنشاء مثيل B.

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

In upcasting and downcasting the  object first upcast then downcastenter
class A
{
}
class B extends A
{
}
Class M
{
  psvm(String ar[])
{

   A a1= new B();
   B b2=(B)a1;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top