2010-05-08 13 views
16

कोई भी विस्तार से समझा सकता है क्योंकि ओवरलोडेड विधि print(Parent parent) कोड के परीक्षण परीक्षण में Child उदाहरण के साथ काम करते समय लागू किया गया है?जावा विधि ओवरलोडिंग + डबल प्रेषण

आभासी तरीकों या तरीकों जावा में/संकल्प यहां शामिल अधिक भार का कोई भी pecularities? जावा लैंग स्पेक के लिए कोई सीधा संदर्भ? कौन सा शब्द इस व्यवहार का वर्णन करता है? बहुत बहुत धन्यवाद।

public class InheritancePlay { 

    public static class Parent {   
     public void doJob(Worker worker) { 
      System.out.println("this is " + this.getClass().getName()); 

      worker.print(this); 
     } 
    } 

    public static class Child extends Parent { 
    } 

    public static class Worker { 
     public void print(Parent parent) { 
      System.out.println("Why this method resolution happens?"); 
     } 

     public void print(Child child) { 
      System.out.println("This is not called"); 
     } 
    } 

    public static void main(String[] args) { 
     Child child = new Child(); 
     Worker worker = new Worker(); 

     child.doJob(worker); 
    } 
} 

उत्तर

23

§8.4.9 Overloading में JLS कहता है:

  1. जब एक विधि शुरू हो जाती है (§15.12), वास्तविक तर्क की संख्या (और किसी भी स्पष्ट प्रकार तर्क) और तर्क हैं की संकलन समय प्रकार उपयोग किए जाने वाले विधि के हस्ताक्षर को निर्धारित करने के लिए संकलित समय पर उपयोग किया जाता है (§15.12.2)।
  2. तरीका है कि लागू किया जा करने के लिए एक उदाहरण विधि है, तो वास्तविक विधि लागू किया जा करने के लिए रन टाइम पर निर्धारित किया जाएगा, गतिशील विधि देखने का उपयोग कर (§15.12.4)।

तो आपके मामले में:

  1. विधि तर्क (this) संकलन समय प्रकार Parent की है, और इसलिए विधि print(Parent) शुरू हो जाती है।
  2. यदि Worker वर्ग उप-वर्गीकृत किया गया था और उपclass उस विधि को ओवरराइड कर देगा, और worker उदाहरण उस सबक्लास का था, तो ओवरराइड विधि लागू की जाएगी।

डबल प्रेषण जावा में मौजूद नहीं है। आपको इसे अनुकरण करना होगा, उदा। Visitor Pattern का उपयोग करके। इस पद्धति में, मूल रूप से, प्रत्येक उपवर्ग एक accept विधि को लागू करता है और this तर्क के रूप में साथ आगंतुक कहता है, और this के रूप में संकलन समय टाइप कि उपवर्ग है, तो वांछित विधि ओवरलोडिंग प्रयोग किया जाता है।

+0

ईसाई, संपूर्ण उत्तर के लिए धन्यवाद! तो हम यहां रनटाइम वीएस संकलन प्रकार की चीज़ के साथ सौदा करते हैं। मैं उस विषय में बहुत कुछ खोदूँगा। (डबल प्रेषण का उल्लेख यहां किया गया है क्योंकि मैं इस प्रश्न में बहुत विज़िटर पैटर्न को साझा कर रहा हूं :))। अधिकतम – Max

5

कारण यह है कि doJobParent में कार्यान्वित किया जाता है और Child में अतिभारित नहीं है। यह कार्यकर्ता print methos को this गुजरता है, क्योंकि this प्रकार Parent विधि Worker::print(Parent) कहा जाएगा की है।

आदेश Worker::print(Parent) आप कहा जाता है करने के लिए Child में अधिभार doJob needto:

public static class Child extends Parent { 
    public void doJob(Worker worker) { 
     System.out.println("from Child: this is " + this.getClass().getName()); 

     worker.print(this); 
    } 
} 

this.getClass() उपरोक्त कोड में Child में Child.class के बराबर है।

+0

आरएसपी, इस ओर इशारा करते हुए के लिए धन्यवाद, लेकिन मुझे पता है कि बच्चे में doJob अधिभावी बनाता prog काम करते हैं। बात यह है कि मुझे समझ में नहीं आता क्यों :)। चलिए प्रारंभिक कोड देखें। जब हम Parent.doJob अंदर Parent.doJob जावा प्रतिबिंब को बाल वस्तु पारित साबित करता है कि हम प्रकार बाल के इस के साथ सौदा, तो क्यों अतिभारित विधि का संकल्प विफल रहता है? – Max

+1

@ मैक्स, एक विधि के अंदर 'इस' प्रकार का प्रकार हमेशा उस वर्ग का प्रकार होता है जिसमें विधि है।संकलक यह नहीं जान सकता कि कक्षा भविष्य में विरासत में जा रही है, इसे उस बिंदु पर ज्ञान का उपयोग करना है। 'this.getClass()' रनटाइम जानकारी है, समय संकलित नहीं है। – rsp

+0

आरएसपी, बहुत बहुत धन्यवाद। पूर्व में ही इसे प्राप्त कर लिया। – Max

संबंधित मुद्दे