2008-12-12 10 views
13

मेरा सवाल यह है कि यदि एक इंटरफ़ेस जिसे पहले से लागू करने वाले वर्ग को विस्तारित करके लागू किया गया है, तो वर्ग को स्पष्ट रूप से लागू किया जाना चाहिए, यदि वर्ग इस तथ्य का विज्ञापन करना चाहता है, तो वह उस इंटरफ़ेस के अनुबंध को पूरा करता है।क्या बेस-क्लास से विरासत में प्राप्त एक इंटरफ़ेस को उपclass में स्पष्ट रूप से कार्यान्वित किया जाना चाहिए?

उदाहरण के लिए, यदि आप कक्षा लिखना चाहते हैं, तो इंटरफ़ेस java.util.List के अनुबंध को पूरा करता है। आप इसे लागू करते हैं, कक्षा java.util.AbstractList को विस्तारित करते हैं, जो पहले ही इंटरफ़ेस List लागू करता है। क्या आप स्पष्ट रूप से घोषणा करते हैं कि आप सूची लागू करते हैं?

public class MyList extends AbstractList implements List 

या आप अंतर्निहित तरीका का उपयोग करके टाइपिंग सहेज सकता हूँ?

public class MyList extends AbstractList 

किस तरह से बेहतर शैली माना जाता है? आपको एक तरफ या किसी अन्य को पसंद करने के लिए क्या कारण हैं? किस स्थितियों में आप 1 या रास्ता 2 पसंद करेंगे?

+0

मुझे लगता है कि यह एक अच्छा सवाल है। – Uri

+0

उपयोगिता दृष्टिकोण से, यह समझ में आता है कि यह क्लास नाम से स्पष्ट नहीं है कि यह इंटरफ़ेस लागू करता है। – Uri

उत्तर

4

मैंने this same question long ago on my blog से पूछा। वहां कुछ लंबी चर्चा भी है यदि आप कुछ अन्य लोगों के विचारों को देखने में रूचि रखते हैं। यह ध्यान रखना दिलचस्प है कि दोनों रणनीतियों को जेडीके के भीतर लिया जाता है।

मैंने अंततः निर्णय लिया कि इस पर एक कठिन नियम समझ में नहीं आया - यह बेहतर है कि मैं किस संवाद के बारे में बात करना चाहता हूं।

12

बचें अतिरेक। उपयोग विधि 2.

ओवरराइड के लिए @Override का प्रयोग करें।

7

यह एक "शैली" सवाल नहीं है। यदि आप सारसूची को विस्तारित कर रहे हैं जो पहले से ही सूची लागू करता है तो आपको सूची को स्पष्ट रूप से कार्यान्वित करने की आवश्यकता नहीं है।

यह टाइपिंग की बचत का सवाल नहीं है। चूंकि अतिरिक्त "उपकरण सूची" अनावश्यक है, इसलिए कोई यह समझने की कोशिश कर सकता है कि यह क्यों है। आप अनिवार्य रूप से ऐसी गारंटी में लिख रहे हैं जो पहले से ही भाषा का हिस्सा है।

+5

क्या होता है यदि कोई और सूची सूची को लागू करने के लिए सारसूची को बदलता है? तो माईलिस्ट टूट गया है? मुझे नहीं लगता कि यह एक मजबूत तर्क है लेकिन सिर्फ शैतान के वकील को खेल रहा है। –

+0

मैं एलेक्स की टिप्पणी +1 करूंगा। – Uri

+0

ठीक है, तो, किसी भी मामले में यह टूट गया है। यदि आप सारसूची सूची के साथ-साथ सूची को लागू करना चाहते थे, तो आपका मतलब कुछ ऐसा था जो वास्तव में कुछ भी नहीं है जब सूची पहले से ही सार सूची लागू करती है। यदि कोई बाद में सूची के साथ आता है और सूची बदलता है, तो यह अब सारसूची को लागू नहीं करता है, फिर, सुनिश्चित करें कि आपके अतिरिक्त "उपकरण" का अर्थ कुछ है, लेकिन शाब्दिक रूप से परिभाषा के अनुसार यह ऐसा कुछ नहीं है जिसका अर्थ आप समझ सकते थे या जब आपने मूल रूप से अपनी सूची लिखी थी प्रथम स्थान। –

0

जब आप सारसूची का विस्तार करते हैं, तो MyList पहले से ही 'प्रकार' सूची का है, इसलिए इंटरफ़ेस को स्पष्ट रूप से stat (या कार्यान्वित) करने की आवश्यकता नहीं है।

1

मैं और अधिक शब्दशः तरह से कह सकते हैं कि। दूसरों को आपके कोड को पढ़ने के लिए क्यों एक वर्ग लागू करने के लिए देखना है? यह आपकी कक्षा की विरासत कार्यक्षमता से स्पष्ट करता है। लेकिन मैं परियोजना में सभी कोडों में स्थिरता बनाए रखने की कोशिश करता हूं। यह भ्रमित हो जाएगा यदि आप केवल एक ही स्थान पर करते हैं लेकिन यदि आप लगातार इसे करते हैं तो वे अनावश्यकता से अवगत होंगे।

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

1

अन्य टिप्पणीकारों का कहना है कि आपको अनावश्यकता से बचना चाहिए, और मैं उनके साथ सहमत हूं।

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

0

एक सामान्य नियम के रूप में, विकल्प 2, नहीं विकल्प 1.

विकल्प 1 का उपयोग डेवलपर या कोई है जो कोड बनाए रखने के लिए जा रहा है अधिकांश मामलों में, के लिए किसी भी मूल्य संवर्द्धन प्रदान नहीं करता है। ।

कोई वास्तव में सभी जड़ों एक विशेष वर्ग के जानना चाहता है, तो किसी भी आईडीई, सीधी आप के लिए यह करने के लिए सक्षम होना चाहिए। (ग्रहण: ctrl + shift + g)

क्या होगा यदि सारसूची सूची को लागू करने का निर्णय नहीं लेती है? यह सामान्य कक्षाओं के विशाल बहुमत के लिए नहीं होने वाला है। अन्य कम स्पष्ट (कम भरोसेमंद) के बारे में क्या? बेशक अपवाद हो सकते हैं, लेकिन बहुत कम (< 1%?)

1

जबकि मैं आमतौर पर विकल्प 2 के साथ चिपक जाता हूं, मैं एक अंग पर जाऊंगा और तर्क दूंगा कि विकल्प 1 लागू होने पर अधिक मामलों में वास्तव में उपयुक्त है।

कोड उपयोगिता और समझदारी महत्वपूर्ण है। सवाल यह है कि हमें खुद से पूछना है कि क्या इस वर्ग के संदर्भ का उपयोग करने या देखने वाला कोई डेवलपर सहजता से समझता है कि कक्षा उस इंटरफ़ेस को लागू करती है (और इस प्रकार अनिवार्य रूप से एक उप प्रकार है)।

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

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

0

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

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

2

यदि आप कक्षा के किसी उपयोगकर्ता को क्लास.getइंटरफेस() के माध्यम से कार्यान्वित इंटरफेस की एक सूची प्राप्त करने में सक्षम होने के बारे में परवाह करते हैं तो आपकी कक्षा को सभी 'इंटरफेस सूची' में सभी इंटरफेस का उल्लेख करना चाहिए। Class.getInterfaces() सुपर क्लास द्वारा कार्यान्वित इंटरफेस वापस नहीं करेगा। निम्नलिखित कार्यक्रम 1 प्रिंट होगा और उसके बाद 0.

import java.io.Serializable; 

class Test implements Serializable { 
    class Inner extends Test { 
    } 

    public static void main(String[] argv) throws Exception { 
     System.out.println(Test.class.getInterfaces().length); 
     System.out.println(Inner.class.getInterfaces().length); 
    } 
} 
1

हालांकि यह उपवर्ग में इंटरफ़ेस लागू करता है करने के लिए अतिरेक है, लेकिन इसे लागू करने के लिए एक अच्छा अभ्यास है। क्योंकि कोई सुपर क्लास से लागू इंटरफेस को हटा सकता है।

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

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