2012-05-14 16 views
8

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

abstract public class AbstractPieceSequence implements PieceSequence 
{ 
    private Tetromino current; 
    private Tetromino preview; 

    public AbstractPieceSequence() 
    { 
     advance(); 
    } 

    @Override 
    public final void advance() 
    { 
     if (preview == null) { 
      current = getNextPiece(); 
      preview = getNextPiece(); 
     } else { 
      current = preview; 
      preview = getNextPiece(); 
     } 
    } 

    abstract protected Tetromino getNextPiece(); 
} 

public class ShufflePieceSequence extends AbstractPieceSequence 
{ 
    private List<Shape> bag = new LinkedList<Shape>(); 

    @Override 
    protected Tetromino getNextPiece() 
    { 
     if (bag.size() == 0) { 
      Collections.addAll(bag, Shape.I, Shape.J, Shape.L, Shape.O, Shape.S, Shape.T, Shape.Z); 
     } 

     return Tetromino.tetrominoes.get(bag.remove(0)); 
    } 
} 

माता पिता के निर्माता कॉल बच्चे वर्ग है, जो List<Shape> bag के मूल्य के रूप में एक अपवाद फेंकता में एक विधि वर्तमान में रिक्त है।

मैं एक बच्चे के कन्स्ट्रक्टर को परिभाषित कर सकता हूं और सुपर() को कॉल कर सकता हूं, लेकिन यह कन्स्ट्रक्टर बॉडी में पहली पंक्ति होनी चाहिए (जिसका मतलब है कि मुझे अभी भी getNextPiece कहा जाता है) से पहले बैग शुरू करने का मौका नहीं है।

मुझे कुछ स्पष्ट याद आ रहा है।

उत्तर

15

यह सही है। super(), भले ही आप इसे स्पष्ट रूप से नहीं जोड़ते हैं, हर कन्स्ट्रक्टर में निहित रूप से रखा गया है। इसका मतलब है कि ShufflePieceSequence के निर्माता को पहले कहा जाता है, लेकिन यह बहुत ही चीज है जो AbstractPieceSequence पर कॉल कर रहा है।

AbstractPieceSequence में आप ShufflePieceSequence में परिभाषित विधि को कॉल कर रहे हैं - जिसे प्रारंभ नहीं किया गया है। वास्तव में आप जो कर रहे हैं वह वास्तव में बहुत सूक्ष्म बग है। कन्स्ट्रक्टर से आपको ओवरराइडबल (abstract विधियों सहित) कभी भी कॉल नहीं करना चाहिए। अवधि। और जैसे AFAIR टूल इसे संभावित बग के रूप में चिह्नित कर रहे हैं।

भी

4

ऑब्जेक्ट फ़ील्ड्स को पूरी तरह से प्रारंभ नहीं किया गया है ... आपको इनिट करने की आवश्यकता है। शायद आपको इस मामले में आलसी init की जरूरत है? आमतौर पर गैर-तुच्छ काम करने वाले कन्स्ट्रक्टर कॉलिंग विधियों के लिए अप्रिय, यह आमतौर पर एक गंध है कि कुछ ऐसा होना अधिक जटिल है।

3

गहराई पहले, एक पूर्व-आदेश चलना।

एंडर्स एक अच्छा बिंदु बनाता है: जावा केवल उन क्षेत्रों को प्रारंभ करता है जो देशी प्रकार हैं। कोई ऑब्जेक्ट फ़ील्ड केवल ऑब्जेक्ट का संदर्भ है, और इसलिए इसे वास्तव में प्रारंभ किया गया है, लेकिन इसे null में प्रारंभ किया गया है।

0

विरासत के मामले में अभिभावक उप वर्ग के कंस्ट्रक्टर्स लागू की आदेश है देखें कि, जनक वर्ग के निर्माता हमेशा पहले और फिर चाइल्ड क्लास के कन्स्ट्रक्टर का आह्वान किया जाता है।

उप-वर्ग सुपर() का उपयोग करके डिफ़ॉल्ट रूप से आधार वर्ग के निर्माता को स्पष्ट रूप से नहीं दिया जाता है।