2015-06-30 16 views
16

पर ओवरलोडिंग विधि सरल प्रश्न, अजीब परिणाम। मैं दो वर्गों A और B है:विस्तारित वर्ग

public class A 
{ 
    protected int num; 

    public A(int n) 
    { 
     num = n; 
    } 

    public boolean f(A a) 
    { 
     return num == a.num * 2; 
    } 
} 

public class B extends A 
{ 
    public B(int n) 
    { 
     super(n); 
    } 

    public boolean f(B b) 
    { 
     return num == b.num; 
    } 
} 

क्यों y1.f(y2) कॉल A बजाय B में में f() विधि?

A y1 = new B(10); 
B y2 = new B(10); 

System.out.println(y1.f(y2)); 

यह रूप में BA की तुलना में अधिक विशिष्ट है B में f() फोन करने वाला नहीं है?

उत्तर

32

y1.f (y2) बी में बजाय ए में f() विधि को क्यों कहते हैं?

क्योंकि y1 का संकलन समय प्रकार A है।

ओवरलोडिंग संकलन समय में किया जाता है ... वस्तु आप पर विधि कॉल के निष्पादन के समय प्रकार अधिभावी के लिए ही प्रासंगिक है।

तो संकलक f(A) विधि का चयन कर रहा है क्योंकि यह केवल f विधि है, यह पता है कि यह y1 पर कॉल कर सकता है (और यह जांच है कि यह तर्क सूची दी गई है)। B में उस विधि को ओवरराइड नहीं किया गया है, इसलिए निष्पादन समय पर, A में इम्प्लेमेनेटेशन कहा जाता है। ,

Object x = "foo"; 
int length = x.length(); 

यह भी संकलित नहीं करेगा क्योंकि Object एक length() विधि शामिल नहीं है:

एक बढ़ता उदाहरण के रूप में, इस कोड पर विचार करें। String करता है, लेकिन संकलक उस पर विचार नहीं करता है, क्योंकि x का संकलन-समय प्रकार Object है, String नहीं - भले ही हम निष्पादन समय पर बता सकें, x का मान String ऑब्जेक्ट का संदर्भ होगा।

+0

हालांकि @ जॉनस्केट का जवाब हमेशा निर्विवाद है .. बस इसे बाइट कोड के साथ भी समर्थन कर रहा है .. आप यह भी देख सकते हैं कि कौन सी विधि बीत रही है और आप इसे देख सकते हैं कि संकलित कोड '(y1.f (y2))' जब आप बाइट कोड '25: invokevirtual # 27 // विधि com/package1/Af: (Lcom/p ackage1/A;) Z' –

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