2010-09-23 15 views
5

मैं कई समान फ़ाइलों को पढ़ने के लिए Scanner class का उपयोग करता हूं। मैं यह सुनिश्चित करने के लिए इसे विस्तारित करना चाहता हूं कि वे सभी एक ही डेलीमीटर का उपयोग करें और मैं skipUntilYouFind (इसे स्ट्रिंग करना) जैसी विधियां भी जोड़ सकता हूं जो सभी उनके लिए मान्य हैं।java.util.Scanner क्लास को 'अंतिम' क्यों घोषित किया गया है?

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

मुझे क्लास फाइनल घोषित करने के लिए some reasons मिला है, लेकिन यह यहां क्यों किया जाता है?

+0

यदि यह प्रदर्शन-संबंधित है, तो क्या यह सिद्धांत में गैर-प्रदर्शन स्कैनर को विस्तारित करना संभव होगा? मेरा तर्क कहता है कि यह होना चाहिए? – Roalt

उत्तर

4

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

उदाहरण के लिए, कक्षा में निम्न विधि पर विचार करें:

public boolean nextBoolean() { 
    clearCaches(); 
    return Boolean.parseBoolean(next(boolPattern())); 
} 

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

तो मूल रूप से ऐसा इसलिए है कि वे कक्षा के अंदर छिपे हुए हिस्सों को आसानी से बदल सकते हैं, जो काफी जटिल हैं, और एक टूटी हुई बाल कक्षा (या एक कक्षा जिसे आसानी से टूटा जा सकता है) बनाने से आपको बचाया जा सकता है।

+0

यह समझाएगा कि फ़ंक्शन अगली बुओलियन को 'अंतिम सार्वजनिक बूलियन अगली बुलीयन()' के रूप में परिभाषित क्यों किया जाना चाहिए, न कि संपूर्ण वर्ग? – Roalt

+0

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

+1

इस तर्क से, सब कुछ एक अंतिम कक्षा होना चाहिए। मैं ईमानदारी से विश्वास नहीं कर सकता कि यही कारण है। – corsiKa

0

मुझे लगता है कि आपके द्वारा प्रदान किया गया लिंक यह सब बताता है।

आपके मामले में ऐसा लगता है कि आपको वैसे भी विरासत की बजाय संरचना को प्राथमिकता देना चाहिए। आप एक उपयोगिता बना रहे हैं जिसमें कुछ पूर्वनिर्धारित व्यवहार है, और यह स्कैनर वर्ग के विवरण के कुछ (या सभी) को छुपा सकता है।

मैंने कई कार्यान्वयन देखा है जो व्यवहार को बदलने के लिए विरासत का उपयोग करते हैं। अंत परिणाम आम तौर पर एक मोनोलिथिक डिजाइन था, और कुछ मामलों में, एक टूटा अनुबंध, और/या टूटा व्यवहार।

+0

इसे एक रचना बनाना मेरे कोड का आकार बढ़ाएगा। यह पाप नहीं है, लेकिन आप my.scanner.next() (या यहां तक ​​कि my.getScanner() भी। Myxt() के बजाय my.getScanner()। (मुझे लगता है कि यह कम सुंदर है, है ना? और यह कम है "इसे बदलें "द्वारा" ... " – Roalt

+0

ठीक है, अगर आपको yourObject.scanner.next() है तो यह सही नहीं है? लेकिन अगर आपके पास yourObject.process (इनपुट) है: returnVal तो आप करते हैं। –

1

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

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