2012-09-27 36 views
8

हाल ही में, मुझे एक आंतरिक कक्षा का उदाहरण बनाने के लिए जावा के <instance>.new निर्माण का उपयोग करने का अवसर मिला।क्या जावा का डॉट नया कोड गंध बनाता है?

जबकि मुझे लगता है कि ऐसा करने के लिए उचित औचित्य था, इसके बजाय अस्पष्ट वाक्यविन्यास ऐसा लगता है कि यह रखरखाव प्रोग्रामर के लिए चीजों को समझना थोड़ा मुश्किल हो सकता है।

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

क्या < उदाहरण > के लिए कोई उपयोग केस हैं। नया जो आंतरिक वर्ग को बाहरी वर्ग में पुन: सक्रिय करके नियंत्रित नहीं किया जा सकता है?

उत्तर

2

मैंने यह नहीं कहा होगा कि यह आवश्यक रूप से कोड गंध था।

यदि बाहरी और आंतरिक वर्गों के बीच युग्मन मजबूत है, और आंतरिक कक्षा का उपयोग अच्छा encapsulation का प्रतिनिधित्व करता है, तो मैं कहूंगा कि इस निर्माण का उपयोग उचित है। दूसरी तरफ, यदि अमूर्तता पहले से ही कमजोर है, तो आंतरिक वर्ग को शीर्ष स्तर की कक्षा बनाना संभवतः एक बेहतर विचार है।

outer.new Inner() का उपयोग एक रिसाव अबास्ट्रक्शन का सबूत हो सकता है या नहीं भी हो सकता है।

(निर्माण एक अच्छे कारण के लिए भाषा, और तथ्य यह है कि यह शायद ही कभी की जरूरत है इसके उपयोग को अमान्य नहीं है में शामिल किया गया था।)

+0

यह मेरा उपयोग मामला हो सकता है, लेकिन ऐसा लगता है कि अपने माता-पिता के बाहर एक भीतरी कक्षा को तुरंत चालू करने की आवश्यकता इंगित करती है कि encapsulation का स्तर उचित नहीं हो सकता है। यह निर्धारित करने के लिए मुझे क्या देखना चाहिए कि encapsulation उचित है या नहीं? – Kylos

+1

विचार करें कि आंतरिक वर्ग बाहरी वर्ग में "आंतरिक" है या नहीं। इस बात पर विचार करें कि आंतरिक वर्ग का अर्थ बाहरी वर्ग के उदाहरण से स्वतंत्र रूप से उपयोग किया जा सकता है या नहीं। –

+0

असल में, मुझे आश्चर्य है कि इसकी कक्षा के बाहर एक भीतरी कक्षा का उपयोग करने की आवश्यकता इंगित करती है कि एक आंतरिक वर्ग उपयुक्त encapsulation नहीं हो सकता है। – Kylos

4

क्या कोई भी उपयोग के मामले हैं। इन्हें आंतरिक वर्ग को बाहरी कक्षा में दोबारा सुधारकर संभाला नहीं जा सकता है?

वहाँ, कि वाक्य रचना के लिए कोई महत्वपूर्ण उपयोग के मामलों में आम तौर पर कर रहे हैं के रूप में आप हमेशा भीतरी निर्माता छिपाने के लिए और बाहरी वर्ग कारखाने तरीकों के माध्यम से आंतरिक वर्ग उदाहरणों लौट जाने (यदि आप वैसे भी बाहर करने के लिए आंतरिक प्रकार का खुलासा करने का इरादा कर सकते हैं):

public class Outer { 
    public class Inner { 
     private Inner() {} 
    } 

    public Inner createInner() { 
     return new Inner(); 
    } 
} 

क्लाइंट कोड:

Outer outer = new Outer(); 
Inner inner = outer.createInner(); 

तो "कोड गंध" (अगर यह होता है वास्तव में एक कोड गंध) तथ्य यह है कि एक आंतरिक वर्ग मौजूद है में नहीं है, लेकिन वास्तव में कि इसकी सी ऑनस्ट्रक्टर सार्वजनिक रूप से उपलब्ध है (और उपयोग किया जाता है)। लेकिन सावधान मूल्यांकन के बाद, आप समझ सकते हैं कि यह ठीक है

अद्यतन: एक अच्छी बात है कि कैप्सूलीकरण दिखा संकेत टूट गया है Outer उदाहरणों शायद Inner उदाहरणों की तुलना में कम रहता है जब है। उस स्थिति में, Inner उदाहरण Outer पर Outer के लेखक के मुकाबले लंबे समय तक संदर्भ के लिए संदर्भ रख सकते हैं। इससे स्मृति-रिसाव भी हो सकता है।

+0

धन्यवाद। ये कुछ अच्छे विचार हैं। – Kylos

0

ठीक है, एक आंतरिक वर्ग से आप की निजी सदस्यों के लिए उपयोग किया बाहरी वर्ग शीर्ष-स्तरीय कक्षाएं नहीं होती हैं।

लेकिन आप बाहरी वर्ग में एक कारखाना विधि जोड़ सकते हैं, जो आंतरिक वर्ग का एक नया उदाहरण बनाता है।

+0

सच है। आंतरिक वर्ग से छुटकारा पाने के लिए न्यूनतम स्तर पर पैकेज-स्तर की पहुंच की आवश्यकता होगी, इसलिए यदि निजी सदस्यों तक पहुंच महत्वपूर्ण है तो एक आंतरिक कक्षा आवश्यक होगी। – Kylos

0

आंतरिक कक्षाओं का उपयोग करके आपके कोड को समझने में कठिनाई होती है, क्योंकि कक्षाएं अपनी आंतरिक स्थिति साझा करती हैं और इसलिए सूचना छिपाने के सिद्धांत को तोड़ती हैं। कभी-कभी एक आंतरिक कक्षा का उपयोग करने से समाधान लिखना आसान हो सकता है, लेकिन मुझे लगता है कि यह ज्यादातर समय का सबसे अच्छा/साफ समाधान नहीं है।

+0

[आंतरिक कक्षाएं हमेशा गैर स्थैतिक घोंसला वाले वर्ग होते हैं] (http://docs.oracle.com/javase/tutorial/java/javaOO/summarynested.html) –

+0

मैंने पहले "नेस्टेड" लिखा था, लेकिन फिर इसे आंतरिक के साथ बदल दिया। निश्चित – CQQL

+0

ठीक है, कम से कम गुमनाम आंतरिक कक्षाएं (जो स्वीकार्य रूप से यहां विषय से बाहर है, क्योंकि उनके पास "बाहर" से कॉल करने के लिए कोई कन्स्ट्रक्टर नहीं है), श्रोताओं को लागू करने के लिए काफी आम हैं। जीयूआई कोड में। हालांकि जावा में लैम्ब्डा अभिव्यक्तियां होने के बाद भी उन्हें प्रतिस्थापित किया जा सकता है (वर्तमान में जावा एसई 8 के लिए योजनाबद्ध)। – Puce

0

मैं कक्षा के एक विधि को बहुप्रचारित होने पर आंतरिक वर्ग espscially का उपयोग करता हूं।

  • एक Runnable वर्ग (विधि बहु हो रही युक्त) बनाएँ और एक नया instanciate ग्राहक खुद थ्रेड करते हैं:

    दरअसल, वहाँ की घोषणा धागे के दो स्वच्छ तरीके है। दोष यह है कि ग्राहक को पता होना चाहिए कि उसे मल्टीथ्रेडिंग से निपटना है।

  • नौकरी कक्षा को Runnable के रूप में घोषित न करें, लेकिन inner-class को परिभाषित करना पसंद करें जो स्वयं Runnable लागू कर रहा है। बेशक, यह inner-classpublic होना आवश्यक नहीं है और इसलिए बाहरी वर्ग (नौकरी वर्ग का अर्थ) में सार्वजनिक समर्पित विधि में से एक द्वारा इसे तत्काल किया जाता है। तो, क्लाइंट इस public विधि से संबंधित है कि यह जानने के बिना कि पृष्ठभूमि में धागा बनाया गया है। यदि कल, डेवलपर्स इस नौकरी कक्षा के भीतर किसी भी कारण से मल्टीथ्रेडिंग को हटाने का विकल्प चुनते हैं, तो क्लाइंट को पूरी तरह से अपरिवर्तित रखा जा सकता है।

और आदेश में इस आंतरिक श्रेणी के बाहरी वर्ग 'क्षेत्रों के वारिस के जाने के लिए में, मैं इसे स्थिर नहीं घोषित करते हैं। (आंतरिक कक्षा के विपरीत नेस्टेड क्लास भी कहा जाता है)