2009-09-27 8 views
17

यह एक असली शुरुआत प्रश्न है (मैं अभी भी जावा मूल बातें सीख रहा हूं)।जावा में उनके इंटरफ़ेस नाम के साथ चर घोषित क्यों हैं?

मैं (एक तरह से) को समझ सकता हूँ क्यों तरीकों एक सूची < स्ट्रिंग > बजाय एक ArrayList < स्ट्रिंग >, या क्यों वे एक ArrayList एक सूची पैरामीटर के बजाय स्वीकार करेंगे वापसी होगी। यदि यह विधि में कोई फर्क नहीं पड़ता है (यानी, यदि ArrayList से कोई विशेष विधि आवश्यक नहीं है), तो यह विधि को अधिक लचीला और कॉलर्स के लिए उपयोग करना आसान बना देगा। सेट या मैप जैसे अन्य संग्रह प्रकारों के लिए भी यही बात है।

मैं क्या समझ में नहीं आता: इसे इस तरह स्थानीय चर बनाने के लिए आम बात हो गया लगता है:

List<String> list = new ArrayList<String>(); 

जबकि इस फार्म लगातार कम है:

ArrayList<String> list = new ArrayList<String>(); 

क्या लाभ यहाँ है?

जो कुछ मैं देख सकता हूं वह मामूली नुकसान है: java.util.List के लिए एक अलग "आयात" लाइन जोड़नी है। तकनीकी रूप से, "आयात java.util। *" का उपयोग किया जा सकता है, लेकिन मुझे अक्सर ऐसा नहीं लगता है, शायद इसलिए कि "आयात" लाइनें कुछ आईडीई द्वारा स्वचालित रूप से जोड़े जाती हैं।

उत्तर

20

जब आप पढ़

List<String> list = new ArrayList<String>(); 

आप विचार है कि तुम सब के बारे में List<String> किया जा रहा है परवाह मिलता है और आप वास्तविक क्रियान्वयन पर कम जोर डाल दिया। साथ ही, आप List<String> द्वारा घोषित सदस्यों को स्वयं प्रतिबंधित करते हैं और विशेष कार्यान्वयन नहीं करते हैं। आपको कोई परवाह नहीं है कि आपका डेटा रैखिक सरणी या कुछ फैंसी डेटा संरचना में संग्रहीत है, जब तक यह List<String> जैसा दिखता है।

दूसरी तरफ, दूसरी पंक्ति पढ़ने से आपको यह विचार मिलता है कि कोड पर ArrayList<String> चर के बारे में बताता है। इसे लिखकर, आप निस्संदेह (भविष्य के पाठकों को) कह रहे हैं कि आपको वास्तविक वस्तु प्रकार को अंधाधुंध रूप से नहीं बदला जाना चाहिए क्योंकि शेष कोड पर निर्भर करता है कि यह वास्तव में ArrayList<String> है।

+5

की बजाय एक सूची सूची लौटाएगी, यह सारोफिलिया है। एक कार्यान्वयन बनाम एक दूसरे की क्षमता उस कोड पर निर्भर करती है जो _uses_ परिवर्तनीय है: मैं नहीं देख सकता कि मैं कभी भी कुछ भी चाहता हूं लेकिन दोनों के बीच एक तंग युग्मन। –

+0

"मैं नहीं देख सकता कि मैं कभी भी कुछ भी चाहता हूं लेकिन दोनों के बीच एक तंग युग्मन": क्या इस तथ्य के आधार पर इंटरफेस की पूरी अवधारणा नहीं है कि आप वास्तव में ** ढीला युग्मन चाहते हैं? –

+1

बेशक।लेकिन आप एक समारोह के काम और उसके स्थानीय चर के बीच ढीला युग्मन कब चाहते हैं? खासकर जब संग्रह कार्यान्वयन का चयन करते हैं, क्योंकि विशिष्ट परिस्थितियों के लिए संग्रह अक्सर अनुकूलित होते हैं। –

1

यदि बाद में आप सूची के कार्यान्वयन को बदलना चाहते हैं और उदाहरण के लिए लिंकडलिस्ट (शायद बेहतर प्रदर्शन के लिए) का उपयोग करें, तो आपको पूरा कोड (और एपीआई अगर इसकी लाइब्रेरी) को बदलना नहीं है। यदि ऑर्डर कोई फर्क नहीं पड़ता है तो आपको संग्रह वापस करना चाहिए ताकि बाद में आप इसे आसानी से बदल सकें यदि आपको सॉर्ट करने के लिए आइटम की आवश्यकता होगी।

+0

"क्यों विधियां एक ArrayList " <- इसलिए इसकी एपीआई;) – IAdapter

1

सबसे अच्छा स्पष्टीकरण मैं साथ आ सकता हूं (क्योंकि मैं जावा में अक्सर अन्य भाषाओं में प्रोग्राम नहीं करता) यह है कि यह "कोड-एंड" सूची प्रकार को बदलना आसान बनाता है जबकि एक ही कोड/इंटरफेस सब कुछ पर भरोसा कर रहा है। यदि आप इसे पहले एक अधिक विशिष्ट प्रकार के रूप में घोषित करते हैं, तो बाद में निर्णय लें कि आप एक अलग तरह चाहते हैं ... यदि कोई ऐरेलिस्ट-विशिष्ट विधि का उपयोग करने के लिए होता है, तो यह अतिरिक्त काम है।

बेशक, यदि आप वास्तव में ArrayList- विशिष्ट व्यवहार की आवश्यकता है, तो आप इसके बजाय विशिष्ट चर प्रकार के साथ जाएंगे।

7

इंटरफ़ेस का उपयोग करके आप सूची/मानचित्र/सेट/आदि के अंतर्निहित कार्यान्वयन को तुरंत बदल सकते हैं।

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

2

मैं इस बारे में दूसरे छोर से इस बारे में सोचने का सुझाव दूंगा। आम तौर पर आप एक सूची या एक सेट या किसी अन्य संग्रह प्रकार चाहते हैं - और आप वास्तव में अपने कोड में परवाह नहीं करते कि यह वास्तव में कैसे कार्यान्वित किया जाता है। इसलिए आपका कोड सिर्फ एक सूची के साथ काम करता है और जो कुछ भी करने की ज़रूरत है उसे भी करें ("इंटरफेस के लिए हमेशा कोड" के रूप में भी वाक्यांशित)।

जब आप सूची सूची बनाएं, तो आपको यह तय करने की आवश्यकता है कि आप कौन सा वास्तविक कार्यान्वयन चाहते हैं। अधिकांश उद्देश्यों के लिए ArrayList "पर्याप्त अच्छा" है, लेकिन आपका कोड वास्तव में परवाह नहीं करता है। इंटरफ़ेस का उपयोग करने के लिए चिपके हुए आप इसे भविष्य के पाठक को बताते हैं।

उदाहरण के लिए मेरे पास मेरी मुख्य विधि में डीबग कोड होने की आदत है जो सिस्टम गुणों को System.out पर डंप करता है - आमतौर पर उन्हें सॉर्ट करने के लिए बहुत अच्छा होता है। सबसे आसान तरीका है बस "मानचित्र मानचित्र = नया TreeMap (गुण);" और फिर उनके माध्यम से पुनरावृत्त करें, क्योंकि TreeMap कुंजी को क्रमबद्ध करता है।

जब आप जावा के बारे में अधिक जानेंगे, तो आप यह भी देखेंगे कि इंटरफेस परीक्षण और मॉकिंग में बहुत उपयोगी हैं, क्योंकि आप किसी दिए गए इंटरफ़ेस के अनुरूप रनटाइम पर निर्दिष्ट व्यवहार के साथ ऑब्जेक्ट्स बना सकते हैं। एक उन्नत (लेकिन सरल) उदाहरण http://www.exampledepot.com/egs/java.lang.reflect/ProxyClass.html

-2

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

उदाहरण के लिए हम कहें, हाल ही में मैंने सीशसेट को सिद्धांत डेटा संरचना के रूप में उपयोग और कार्यान्वित करने का तरीका सीखा। मान लीजिए, किसी भी कारण से, मैं एक टीम पर काम करने गया। क्या उस व्यक्ति को यह जानने की ज़रूरत नहीं है कि कुछ आधार से ऑर्डर करने के बजाए डेटा को हैशिंग दृष्टिकोण पर रखा गया था? ट्विसोल द्वारा देखा गया बैक-एंड दृष्टिकोण सी/सी ++ में काम करता है जहां आप हेडर का पर्दाफाश कर सकते हैं और इस प्रकार लाइब्रेरी बेच सकते हैं, अगर कोई जानता है कि जावा में ऐसा कैसे करना है तो मुझे लगता है कि वे जेएनआई का उपयोग करेंगे - जिस बिंदु पर मेरे लिए आसान लगता है सी/सी ++ का उपयोग करने के लिए जहां आप हेडर का पर्दाफाश कर सकते हैं और उस उद्देश्य के लिए स्थापित टूल का उपयोग करके libs का निर्माण कर सकते हैं।

उस समय तक आप किसी ऐसे व्यक्ति को प्राप्त कर सकते हैं जो एक्सटेंशन में एक जार फ़ाइल इंस्टॉल कर सकता है, यह मुझे लगता है कि इकाई कम छोटी दूरी दूर हो सकती है - मैंने एक्सटेंशन निर्देशिका में कई क्रिप्टो libs को छोड़ दिया, जो आसान था, लेकिन मैं वास्तव में स्पष्ट, संक्षिप्त आधार स्पष्ट रूप से देखना चाहता हूं। मुझे लगता है कि वे हर समय ऐसा करते हैं।

इस बिंदु पर यह मुझे क्लासिक obfuscation की तरह लगता है, लेकिन सावधान रहें: इस मुद्दे के परिणाम होने से पहले आपके पास कुछ कोडिंग है।

+0

आपने मुझे अंत में पूरी तरह से खो दिया। – user183037

+2

और मैं। ऐसा लगता है कि आप इंटरफेस के बिंदु को याद कर चुके हैं। इसके अलावा, यहां कोई कास्टिंग नहीं है। – DNA

0

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

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

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