2014-11-19 8 views
5

क्या कोई यह समझा सकता है कि यह कोड आउटपुट को शून्य के रूप में क्यों दे रहा है? जब मैं new B() के बजाय new A() पर कॉल करने का प्रयास करता हूं, तो यह वर्तमान दिनांक प्रिंट कर रहा है।जावा प्रवाह-नियंत्रण

class A 
{ 
    Date d = new Date(); 

    public A() 
    { 
     printDate(); 
    } 

    void printDate() 
    { 
     System.out.println("parent"); 
     System.out.println(d); 
    } 
} 

class B extends A 
{ 
    Date d = new Date(); 

    public B() 
    { 
     super(); 
    } 

    @Override 
    void printDate() 
    { 
     System.out.println("child"); 
     System.out.println(d); 
    } 
} 

public class Test 
{ 
    public static void main(String[] args) 
    { 
     new B(); 
    } 
} 
+1

अच्छा सवाल .. – SonalPM

+0

देखें http://stackoverflow.com/questions/20474521/allowing-the-this-reference-to-escape – Qwerky

उत्तर

1

सभी आदानों, मैं जवाब संतुष्ट निम्नलिखित उम्मीद,

बी भी क्षेत्र घ है के रूप में, A.d बी, जहां बी डी की अपनी एक प्रतिलिपि है करने के लिए विरासत में मिला नहीं है के बाद।

तो जब नियंत्रण बीप्रिंटडेट() में होता है, तो यह एडी को देखने की कोशिश करता है (क्योंकि फ़ंक्शन ए से कहा जाता है)।

इस ठीक काम करता है अगर मैं बी से निम्न पंक्ति को दूर

Date d = new Date(); 
4

नई बी() बी के निर्माता है, जो ए ए के निर्माता के निर्माता का आह्वान कॉल printDate() है, जो, अधिभावी के कारण, कार्यान्वित बी के printDate(), जो B की d चर के मूल्य प्रिंट invokes। हालांकि, dB का चर अभी तक शुरू नहीं हुआ है (इसे केवल ए के कन्स्ट्रक्टर के निष्पादित करने के बाद ही आरंभ किया जाएगा)। इसलिए यह अभी भी शून्य है (जो संदर्भ चर के लिए डिफ़ॉल्ट मान है)।

दूसरी ओर, जब आप A (new A()) का एक उदाहरण बनाने के लिए, A की printDate कहा जाता है, और यह A की d चर, जो A के निर्माता निष्पादित किया जा रहा से पहले प्रारंभ किया गया था प्रिंट करता है।

यदि यह स्पष्ट नहीं है, तो बीडी एडी ओवरराइड नहीं करता है, यह सिर्फ इसे छुपाता है। केवल विधियों को ओवरराइड किया जा सकता है।

+0

क्या आपको यकीन है? 'बी' 'डी' को भी परिभाषित करता है जो 'ए' – ooxi

+1

' एडी 'से छाया' डी '' बीप्रिंटडेट() ' –

+0

@ooxi से दिखाई नहीं दे रहा है यह सही है। यही कारण है कि बी का प्रिंट प्रिंट() 'बी – Eran

1

घोषित Date स्टेटिक रूप

static Date d = new Date(); 
    public B(){ 
     super(); 
    } 
    @Override 
    void printDate(){ 
     System.out.println("child"); 
     System.out.println(d); 
    } 
+0

ये, मुझे पता है कि यह स्थिर है अगर मैं स्थिर जोड़ता हूं, लेकिन मैं जानना चाहता हूं कि मेरा कोड क्यों विफल रहा है। और जब मैं नया ए कॉल करता हूं() क्यों यह असफल नहीं होता है। – chiranjeevi

1

जब आप एक B का दृष्टांत: एक निर्माता

  • एक निर्माता कहता है printDate को

    1. बी निर्माता चेन, लेकिन यहहैओवरराइड जिसे

    2. B.printDate प्रिंट B.d कहा जाता है।

    3. कि null देता है क्योंकि B.d क्षेत्र

    4. printMethod रिटर्न प्रारंभ नहीं किया गया है, और A निर्माता रिटर्न

    5. B के क्षेत्र प्रारंभ कर रहे हैं, एक गैर-शून्य करने के लिए B.d की स्थापना मूल्य। लेकिन आउटपुट को प्रभावित करने में बहुत देर हो चुकी है।


    कुछ सबक इस से जानने के लिए:

    • यह एक निर्माता वस्तु यह पैदा कर रही है पर एक उदाहरण विधि कॉल करने के लिए एक बुरा विचार है, जब तक कि उदाहरण विधि है या तो private या final। यदि आप उप-वर्ग द्वारा ओवरलोड किए गए किसी विधि को कॉल करने का प्रबंधन करते हैं, तो उस विधि को प्रारंभ करने से पहले उपclass के आवृत्ति चर दिखाई देगा ... और यह समस्याग्रस्त है।

    • एक वर्ग और उप-वर्ग द्वारा एक (गैर-निजी) फ़ील्ड के लिए समान नाम का उपयोग करना एक बुरा विचार है। दोनों फ़ील्ड मौजूद होंगे, और किसी को कोड को पढ़ने के लिए यह मुश्किल हो सकता है ताकि वह इसे अपने सिर में रख सके।

    • गैर-निजी उदाहरण फ़ील्ड एक बुरा विचार है। वे encapsulation के लिए बुरे हैं।

  • 1

    इसका कारण यह है कि जब आप सुपर फोन() तो दिनांक चर घ वर्ग एक में परिभाषित प्रारंभ हो जाता है। कक्षा बी में से वैरिएबल डी एक ऑब्जेक्ट वैरिएबल है, और यह वैरिएबल डी को वैरिएबल क्लास से ओवरराइट करता है, और ऑब्जेक्ट वैरिएबल का निर्माण केवल this पॉइंटर के निर्माण के बाद किया जाता है, आप शून्य हो रहे हैं। यदि आप चाहते हैं कि काम करने की अपेक्षा करें, कक्षा बी में वैरिएबल वैरिएबल को वैरिएबल वैरिएबल के रूप में बनाएं, जिसे क्लास लोडिंग के साथ शुरू किया जाएगा।