سؤال

مرحبا جميعا،

أتساءل عما إذا كان هناك أي من متسللي Java الذين يمكنهم إرشادي إلى سبب عدم نجاح ما يلي:

public class Parent {
    public Parent copy() {
       Parent aCopy = new Parent();
       ...
       return aCopy;
    }
}

public class ChildN extends Parent {
    ...
}

public class Driver {
     public static void main(String[] args) {
         ChildN orig = new ChildN();
         ...
         ChildN copy = orig.getClass().cast(orig.copy());
     }
}

الكود سعيد جدًا بالتجميع، لكنه قرر طرح ClassCastException في وقت التشغيل D=

يحرر: اه، ردود سريعة حقا.شكرا يا شباب!لذلك يبدو أنني لا أستطيع الإحباط باستخدام هذه الطريقة ...هل هناك أي طريقة أخرى للقيام downcasting في جافا؟لقد فكرت في الحصول على كل منهما ChildN الكتابة فوق الفصل copy(), ، لكنه لم يكن متحمسًا لإضافة الكود المعياري الإضافي.

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

المحلول

و(لا يمكن إضافة رمز في تعليق، لذلك سأضيف هنا)

وفيما يتعلق Cloneable: إذا كنت تنفيذ Cloneable وتنفيذ ذلك على النحو التالي؛ أنظف بكثير للاتصال ...

public class Foo implements Cloneable {
    public Foo clone() {
        try {
            return (Foo) super.clone();
        } catch (CloneNotSupportedException e) {
            return null; // can never happen!
    }
}

[تحرير: رأيت أيضا استخدام غيرها من الناس

throw new AssertionError("This should never happen! I'm Cloneable!");

وفي كتلة الصيد.]

نصائح أخرى

يشبه محاولة القيام بذلك:

  public Object copy(){
       return new Object();
  }

ومن ثم حاول:

  String s = ( String ) copy();

لك الأبوين الطبقة و الطفل ن الطبقة لها نفس العلاقة كما هدف و خيط

لجعله يعمل، ستحتاج إلى القيام بما يلي:

public class ChildN extends Parent {
    public Parent copy() {
        return new ChildN();
    }
}

وهذا يعني تجاوز طريقة "النسخ" وإرجاع المثيل الصحيح.


يحرر

حسب تعديلك.وهذا ممكن في الواقع.يمكن أن تكون هذه إحدى الطرق الممكنة:

public class Parent {
    public Parent copy() {
        Parent copy = this.getClass().newInstance();
        //...
        return copy;
    }
}

بهذه الطريقة لن تضطر إلى تجاوز طريقة "النسخ" في كل فئة فرعية.هذا هو نمط تصميم النموذج الأولي.

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

public class Parent {
    public Parent copy()  throws InstantiationException, IllegalAccessException  {
       Parent copy = this.getClass().newInstance();
       //...
       return copy;
    }
}
class ChildN  extends Parent {}

class Driver {
     public static void main(String[] args) throws  InstantiationException ,  IllegalAccessException  {
         ChildN orig = new ChildN();
         ChildN copy = orig.getClass().cast(orig.copy());
         System.out.println( "Greetings from : " + copy );
    }
}

ويلقي وهي تحاول بشكل فعال للقيام بذلك:

ChildN copy = (ChildN) orig.copy();

و(انها تعمل من المدلى بها لأداء في وقت التنفيذ، ولكن هذا ما سوف يكون ذلك بسبب orig.getClass() سيكون ChildN.class) ومع ذلك، orig.copy() لا يرجع مثيل ChildN، فإنها ترجع مثيل Parent فقط، لذلك ما في وسعها 'ر أن يلقي إلى ChildN.

إذا لم ChildN تجاوز نسخة () لإرجاع مثيل ChildN، ثم تحاول مسبل كائن من نوع الأم لكتابة ChildN

وjava.lang.Class # الزهر (كائن) يلقي ClassCastException إذا فئة # isInstance () إرجاع كاذبة. من جافادوك لهذا الأسلوب:

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

وتحديد ما إذا كان الكائن المحدد   احالة متوافق مع الكائن   ممثلة هذه الفئة. هذه الطريقة   هو ما يعادل الديناميكي للجافا   لغة المشغل instanceof ...   على وجه التحديد، إذا كانت هذه   يمثل الكائن Class ل   الطبقة أعلن، هذا الأسلوب يعود   true إذا المحدد   حجة Object هي   مثيل من فئة ممثلة (أو   من أي من الفئات الفرعية)؛ تقوم بإرجاع   false خلاف ذلك.

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

ويمكن أن يكون ذلك كنت تريد ببساطة نسخة / نسخة من وجوه الخاص بك.

في هذه الحالة، وتنفيذ واجهة Cloneable واستنساخ تجاوز () عند الضرورة.

public class Parent implement Cloneable {
   public Object clone() throws CloneNotSupportedException {
     Parent aCopy = (Parent) super.clone();
   ...
   return aCopy;
   }
}

public class ChildN extends Parent {
    ...
}

public class Driver {
     public static void main(String[] args) {
         ChildN orig = new ChildN();
         ...
         ChildN copy = orig.getClass().cast(orig.clone());
     }
}

وهذا يفعل بالضبط ما حاول من طريقة "نسخة ()" يجب القيام به في طريقة جافا.

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

والسبب العمل downcasting] لا لأنه، عند يلقي الكائن الأصل إلى نوع الطفل، لا توجد طريقة يمكنك استدعاء أساليب نوع الطفل على الكائن الأصل. لكنه يعمل بطريقة أخرى ...

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