2010-05-14 20 views
15

मुझे जावा में गैर स्थैतिक घोंसला वाले वर्गों के आसपास अपने सिर को लपेटने में कठिनाई हो रही है। निम्नलिखित उदाहरण पर विचार करें, जो "इनर" और फिर "चाइल्ड" प्रिंट करता है।जावा: गैर स्थैतिक घोंसला वाले वर्ग और उदाहरण। सुपरर()

class Outer { 
    class Inner { 
     Inner() { System.out.println("Inner"); } 
    } 
} 

public class Child extends Outer.Inner { 
    Child(Outer o) { 
     o.super(); 
     System.out.println("Child"); 
    } 
    public static void main(String args[]) { 
     new Child(new Outer()); 
    } 
} 

मैं समझता हूँ इनर के उदाहरण हमेशा एक बाहरी उदाहरण के साथ जुड़े होने के लिए है कि, और कहा कि वह भी बाल पर लागू होता है यह इनर फैली के बाद से। मेरा सवाल यह है कि o.super() वाक्यविन्यास का अर्थ है - यह आंतरिक कन्स्ट्रक्टर को क्यों कॉल करता है?

मैं केवल एक सादे super(args) सुपर क्लास निर्माता बुलाते थे और super.method() देखा है एक ओवरराइड विधि के सुपर क्लास संस्करण, लेकिन कभी प्रपत्र instance.super() के बारे में कुछ कॉल करने के लिए।

+0

एलओएल ... इसमें 'साक्षात्कार-प्रश्न' टैग क्या है? – Cristian

+0

जावा स्थिति के लिए एक साक्षात्कार के हिस्से के रूप में, मुझे एक आईकेएम प्रश्नोत्तरी पूरा करने के लिए कहा गया था; यह प्रश्न प्रश्नोत्तरी पर एक का सरलीकृत रूप है। – Kiv

+0

@ किवी क्या आपको वास्तविक जीवन उपयोग का एक उदाहरण मिला है? – chepseskaf

उत्तर

9

यह एक "योग्य सुपर क्लास निर्माता मंगलाचरण" कहा जाता है।

here से हवाला देते हुए:

  • वैकल्पिक निर्माता आमंत्रण कीवर्ड इस (संभवतः स्पष्ट प्रकार तर्क के साथ आरंभ) के साथ शुरू:

    स्पष्ट निर्माता मंगलाचरण बयान दो प्रकार में विभाजित किया जा सकता है। वे एक ही कक्षा के वैकल्पिक कन्स्ट्रक्टर का आह्वान करने के लिए उपयोग किया जाता है।

  • सुपर क्लास निर्माता आमंत्रण या तो कीवर्ड सुपर (संभवतः स्पष्ट प्रकार तर्क के साथ आरंभ) या एक प्राथमिक अभिव्यक्ति के साथ शुरू करते हैं। इन्हें प्रत्यक्ष सुपरक्लास के निर्माता का आह्वान करने के लिए उपयोग किया जाता है। सुपर क्लास निर्माता आमंत्रण आगे विभाजित किया जा सकता:

  • अयोग्य सुपर क्लास निर्माता आमंत्रण कीवर्ड सुपर (संभवतः स्पष्ट प्रकार तर्क के साथ आरंभ) के साथ शुरू करते हैं।

  • योग्य सुपर क्लास निर्माता आमंत्रण एक प्राथमिक अभिव्यक्ति के साथ शुरू करते हैं। वे एक उप-वर्ग निर्माता को प्रत्यक्ष सुपरक्लास (§8.1.3) के संबंध में नव निर्मित ऑब्जेक्ट के तत्काल संलग्न उदाहरण को स्पष्ट रूप से निर्दिष्ट करने की अनुमति देते हैं। यह आवश्यक हो सकता है जब सुपरक्लास एक आंतरिक वर्ग है।

9

इनर वर्ग (गैर स्थिर बच्चे वर्ग) अनिवार्य रूप से निहित लिंक वापस अपने माता पिता के साथ वस्तुओं के लिए नेस्टेड वर्ग (स्थिर बच्चे वर्ग) कर रहे हैं। यहाँ अपने ऊपर कोड, बजाय एक स्थिर नेस्टेड वर्ग का उपयोग कर लिखा है:

class Outer { 
    static class Inner { 
     final Outer outer; 
     Inner(Outer outer) { 
      this.outer = outer; 
      System.out.println("Inner"); 
     } 
    } 
} 

public class Child extends Outer.Inner { 
    Child(Outer o) { 
     super(o); // o.super(); 
     System.out.println("Child"); 
    } 

    public static void main(String args[]) { 
     new Child(new Outer()); 
    } 
}

इस को देखते हुए, आप को समझने के लिए o.super() क्या कर रहा था सक्षम होना चाहिए।

+2

वास्तव में, मेरी समझ से उपरोक्त के लिए एक गैर स्थैतिक आंतरिक वर्ग अनिवार्य रूप से वाक्य रचनात्मक चीनी है। –

+0

नहीं, एक नेस्टेड स्थैतिक वर्ग अनिवार्य रूप से बाहरी स्तर की कक्षा है, जो केवल पैकेजिंग सुविधा के लिए है। –

+1

ठीक है, ठीक है। मेरा मतलब है कि एक * गैर स्थैतिक * आंतरिक वर्ग सिंटेक्टिक चीनी के शीर्ष पर सिंटेक्टिक चीनी है :- डी –

2

वैचारिक रूप से, एक गैर स्थिर भीतरी वर्ग एक विशेष वस्तु को "अंतर्गत आता है"। यह क्रमबद्ध है जैसे प्रत्येक व्यक्ति को कक्षा का अपना संस्करण मिलता है, एक गैर स्थैतिक क्षेत्र की तरह या विधि किसी विशेष वस्तु से संबंधित होती है।संदर्भों के लिए जहां सवाल "लेकिन जिसकाInner?" का जवाब तुरंत स्पष्ट नहीं है -

तो यही कारण है कि हम instance.new Inner() और instance.super() की तरह अजीब वाक्य रचना है है। (बाहरी वर्ग के एक गैर स्थैतिक विधि में, तुम सिर्फ new Inner() कह सकते हैं, और हमेशा की तरह है कि this.new Inner() के लिए कम है।)

5

क्यों Child में o.super()Outer.Inner निर्माता लागू समाप्त होता है? यह आसान है: क्योंकि Child extends Outer.Inner, और कन्स्ट्रक्टर कॉल हमेशा पदानुक्रम को जंजीर बनाते हैं।

यहाँ अपने टुकड़ा करने के लिए एक मामूली विस्तार वर्णन करने के लिए है:

class Outer { 
    Outer() { 
     System.out.println("Outer"); 
    } 
    void outerMethod() { } 
    class Inner { 
     Inner() { 
      System.out.println("OuterInner"); 
      outerMethod();    
     } 
     String wealth; 
    } 
} 
class OuterChild extends Outer { 
    OuterChild() { 
     System.out.println("OuterChild"); 
    } 
} 
public class OuterInnerChild extends Outer.Inner { 
    OuterInnerChild(Outer o) { 
     o.super(); 
     System.out.println("OuterInnerChild"); 
     this.wealth = "ONE MILLION DOLLAR!!!"; 
    } 
    public static void main(String args[]) { 
     System.out.println(new OuterInnerChild(new Outer()).wealth); 
     new OuterChild(); 
    } 
} 

यह प्रिंट:

Outer 
OuterInner 
OuterInnerChild 
ONE MILLION DOLLAR!!! 
Outer 
OuterChild 

कुछ प्रमुख टिप्पणियों:

  • क्योंकि OuterInnerChild extends Outer.Inner, यह wealth विरासत, जैसे सामान्य सबक्लास अर्थशास्त्र
    • और बस सामान्य उपवर्ग अर्थ विज्ञान की तरह, की Outer.Inner
  • OuterChild extends Outer क्योंकि निर्माता को OuterInnerChild श्रृंखला के निर्माता, अपने निर्माता चेन, यहाँ तक कि जब स्पष्ट रूप से
    • चाहे परोक्ष या स्पष्ट, लागू नहीं पदानुक्रम
अप निर्माता चेन

लेकिन क्यों संकलक मांग है कि OuterInnerChild निर्माता एक Outer o लेता है, और है कि o.super() शुरू हो जाती है करता है?

अब जब कि भीतरी वर्ग अर्थ विज्ञान के लिए विशिष्ट है: यह सुनिश्चित करना है कि OuterInnerChild के सभी उदाहरणों एक Outer.Inner, OuterInnerChild के सुपर वर्ग के लिए संलग्न है Outer उदाहरण किया है। अन्यथा, Outer.Inner के निर्माता Outer का एक संलग्न उदाहरण नहीं होगा outerMethod() पर।

0

हमेशा उप-वर्ग कन्स्ट्रक्टर को कॉल करने की प्रक्रिया में बुनियादी सिद्धांतों को न भूलना, यह हमेशा माता-पिता को आंतरिक/बाहरी वर्गों के बावजूद पहले तत्काल स्थापित किया जाता है। आपके परिदृश्य में, जैसा कि आप आंतरिक वर्ग का विस्तार कर रहे हैं और आपकी आंतरिक कक्षा अभिभावक वर्ग का सदस्य है जिसे तत्काल स्थापित करने की आवश्यकता होती है और उसके बाद वास्तविक आंतरिक वर्ग कन्स्ट्रक्टर को कॉल किया जाता है।

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