سؤال

أمس كان لي ساعتين التقنية مقابلة عبر الهاتف (التي مرت ، فوردعالم!), ولكن أنا تماما muffed التالية سؤال حول الربط الديناميكي في جاوة.و هو مضاعف الحيرة لأنني كنت تعلم هذا المفهوم إلى الطلاب الجامعيين عندما كنت تا قبل بضع سنوات ، وبالتالي فإن احتمال أن أعطى لهم التضليل أمر مزعج قليلا...

هنا المشكلة أنا أعطيت:

/* What is the output of the following program? */

public class Test {

  public boolean equals( Test other ) {
    System.out.println( "Inside of Test.equals" );
    return false;
  }

  public static void main( String [] args ) {
    Object t1 = new Test();
    Object t2 = new Test();
    Test t3 = new Test();
    Object o1 = new Object();

    int count = 0;
    System.out.println( count++ );// prints 0
    t1.equals( t2 ) ;
    System.out.println( count++ );// prints 1
    t1.equals( t3 );
    System.out.println( count++ );// prints 2
    t3.equals( o1 );
    System.out.println( count++ );// prints 3
    t3.equals(t3);
    System.out.println( count++ );// prints 4
    t3.equals(t2);
  }
}

وأكدت أن الإخراج كان ينبغي أن يكون اثنين منفصلة طباعة البيانات من داخل تجاوز equals() الطريقة:في t1.equals(t3) و t3.equals(t3).الحالة الأخيرة هو واضح بما فيه الكفاية ، مع الحالة السابقة ، على الرغم من t1 وقد إشارة من نوع Object, فمن مثيل حسب نوع الاختبار ، لذلك الربط الديناميكي يجب استدعاء تجاوز شكل من طريقة.

على ما يبدو لا.بلدي المقابلة شجعني على تشغيل البرنامج على نفسي ، وها ، لم يكن هناك سوى واحد خرج من تجاوز الأسلوب:في خط t3.equals(t3).

سؤالي هو: لماذا ؟ كما ذكرت بالفعل ، على الرغم من t1 هو إشارة من نوع Object (حتى ثابت ملزم أن الاحتجاج الكائن equals() طريقة) ، الربط الديناميكي يجب أن تأخذ الرعاية من الاحتجاج الأكثر تحديدا نسخة من طريقة تقوم على إنشاء مثيل نوع من المرجعية.ما أنا في عداد المفقودين ؟

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

المحلول

جافا يستخدم ثابتة ملزمة طاقتها أساليب الربط الديناميكي على تجاوز تلك.في المثال الخاص بك ، يساوي طريقة طاقتها (قد تختلف المعلمة نوع من الكائن.يساوي ()) ، وبالتالي فإن طريقة تسمى منضما إلى المرجعية نوع في وقت الترجمة.

بعض المناقشة هنا

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

تحرير:وصفا جيدا هنا وكذلك.هذا المثال يظهر مشكلة مشابهة تتعلق المعلمة نوع بدلا من ذلك ، ولكن بسبب نفس المشكلة.

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

نصائح أخرى

وطريقة equals من Test لا يتجاوز طريقة equals من java.lang.Object. نظرة على نوع المعلمة! الطبقة Test والحمولة الزائدة equals مع طريقة يقبل Test.

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

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

وجافا لا يدعم التغاير في المعلمات، إلا في أنواع العودة.

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

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

وحظا سعيدا مع عملية المقابلة وظيفة! أحب لإجراء مقابلات معهم في الشركة التي تطلب هذه الأنواع من الأسئلة بدلا من الأسئلة الهياكل البرودة؛ الصقيع / البيانات المعتادة التي أدرس طلابي.

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

وطاقتها أسلوب بدلا من تنقضها. يساوي دائما تأخذ كائن كمعلمة.

وراجع للشغل، لديك عنصر على هذا في جافا بلوخ الفعال (التي يجب أن تملكها).

ملاحظة في بعض الربط الديناميكي (DD) ، ثابت ملزم(SB) بعد البحث في كل حين:

1.توقيت تنفيذ:(Ref.1)

  • DB:في وقت التشغيل
  • SB:مترجم الوقت

2.تستخدم:

  • DB:تجاوز
  • SB:الحمولة الزائدة (ثابت, خاص, النهائي) (Ref.2)

المرجع:

  1. تنفيذ يعني محلل الطريقة التي تفضل استخدام
  2. لأنه لا يمكن تجاوز الأسلوب مع معدل ثابت أو الخاص أو النهائي
  3. http://javarevisited.blogspot.com/2012/03/what-is-static-and-dynamic-binding-in.html

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

/ * ما هو الناتج من البرنامج التالي؟ * /

public class DynamicBinding {
    public boolean equals(Test other) {
        System.out.println("Inside of Test.equals");
        return false;
    }

    @Override
    public boolean equals(Object other) {
        System.out.println("Inside @override: this is dynamic binding");
        return false;
    }

    public static void main(String[] args) {
        Object t1 = new Test();
        Object t2 = new Test();
        Test t3 = new Test();
        Object o1 = new Object();

        int count = 0;
        System.out.println(count++);// prints 0
        t1.equals(t2);
        System.out.println(count++);// prints 1
        t1.equals(t3);
        System.out.println(count++);// prints 2
        t3.equals(o1);
        System.out.println(count++);// prints 3
        t3.equals(t3);
        System.out.println(count++);// prints 4
        t3.equals(t2);
    }
}

ولقد وجدت مادة مثيرة للاهتمام حول ديناميكية مقابل ساكنة ملزمة. لأنه يأتي مع قطعة من رمز لمحاكاة الربط الحيوي. جعلت قانون بلدي وأكثر قابلية للقراءة.

https://sites.google.com/site/jeffhartkopf/covariance

انظر أيضا هذا السؤال وثيق الصلة: تجاوز جافا يساوي طريقة شاءت

والجواب على السؤال "لماذا؟" غير ان هذه هي الطريقة يعرف لغة جافا.

لأقتبس من مقالة ويكيبيديا على التغاير وContravariance :

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

ويتم تنفيذ نوع العودة التغاير   في لغة البرمجة جافا   إصدار J2SE 5.0. أنواع المعلمة لها   أن يكون بالضبط نفس الشيء (ثابتة) ل   طريقة الغلابة، وإلا فإن   طاقتها الأسلوب مع مواز   تعريف بدلا من ذلك.

لغات أخرى مختلفة.

من الواضح جدا، أنه لا يوجد مفهوم تجاوز هنا. ومن طريقة الحمولة الزائدة. طريقة Object() من الدرجة كائن يأخذ المعلمة مرجعية من نوع الكائن وهذه الطريقة equal() يأخذ المعلمة مرجعية من نوع اختبار.

سوف أحاول أن أشرح ذلك من خلال اثنين من الأمثلة التي هي مدد إصدارات بعض الأمثلة التي جئت عبر الانترنت.

public class Test {

    public boolean equals(Test other) {
        System.out.println("Inside of Test.equals");
        return false;
    }

    @Override
    public boolean equals(Object other) {
        System.out.println("Inside of Test.equals ot type Object");
        return false;
    }

    public static void main(String[] args) {
        Object t1 = new Test();
        Object t2 = new Test();
        Test t3 = new Test();
        Object o1 = new Object();

        int count = 0;
        System.out.println(count++); // prints 0
        o1.equals(t2);

        System.out.println("\n" + count++); // prints 1
        o1.equals(t3);

        System.out.println("\n" + count++);// prints 2
        t1.equals(t2);

        System.out.println("\n" + count++);// prints 3
        t1.equals(t3);

        System.out.println("\n" + count++);// prints 4
        t3.equals(o1);

        System.out.println("\n" + count++);// prints 5
        t3.equals(t3);

        System.out.println("\n" + count++);// prints 6
        t3.equals(t2);
    }
}

هنا خطوط مع عد القيم 0, 1, 2, و 3 ؛ لدينا المرجعية من وجوه بالنسبة o1 و t1 على equals() الأسلوب.وهكذا ، في وقت الترجمة ، equals() طريقة من Object.class الملف سوف يكون يحدها.

ومع ذلك ، على الرغم من المرجعية من t1 هو وجوه, ، فقد intialization من اختبار الفصل.
Object t1 = new Test();.
لذلك ، في وقت التشغيل ويدعو public boolean equals(Object other) وهو

متجاوزة

. enter image description here

الآن عد القيم 4 و 6 مرة أخرى واضحة أن t3 الذي المرجعية و التهيئة الاختبار هو الدعوة equals() الأسلوب مع المعلمة وجوه المراجع هو

زائد طريقة

موافق!

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

enter image description here

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