2011-06-24 19 views
49

मैं हाल ही में जावा सीख रहा हूं, और मैं package-private कक्षाओं की धारणा में आया, जो डिफ़ॉल्ट है अगर हम कुछ भी निर्दिष्ट नहीं करते हैं। लेकिन फिर मुझे एहसास हुआ:जावा में पैकेज निजी कक्षाओं के पेशेवरों और विपक्ष?

  1. मुझे शायद ही कभी पैकेज-निजी वर्ग का उपयोग दिखाई देता है। इसके लिए कोई कारण है, उदाहरण के लिए, इसमें गंभीर कमी है, यह अनावश्यक है, या बस मैं पर्याप्त पढ़ नहीं रहा हूं? क्या इसके उपयोग के लिए/इसके खिलाफ मजबूत तर्क हैं?

  2. यदि यह ज्यादातर मामलों में वास्तव में उपयोगी नहीं है, तो यह डिफ़ॉल्ट क्यों होगा?

  3. वास्तविक स्थिति में पैकेज-निजी का उपयोग किस स्थिति में करना चाहिए? यानी, यह कब अपरिवर्तनीय हो जाएगा?

दूसरे शब्दों में, डिफ़ॉल्ट पैकेज-निजी संशोधक के प्रमुख पेशेवरों और विपक्ष क्या हैं?

उत्तर

41

संक्षिप्त उत्तर यह है - यह निजी का थोड़ा बड़ा रूप है।

मैं मान लेंगे कि आप public और private के बीच के अंतर से परिचित हैं, और क्यों यह आम तौर पर वे सवाल में वर्ग के लिए पूरी तरह से आंतरिक रूप से उपयोग करने जा रहे हैं, तो तरीकों और चर private बनाने के लिए अच्छी आदत है।

ठीक है, कि करने के लिए एक विस्तार के रूप - अगर आप एक मॉड्यूलर तरीके से अपने सॉफ्टवेयर बनाने के बारे में सोच रहे हैं, तो आप अपने मॉड्यूल है, जो कई वर्गों होगा अंदर यह आपस में सहयोग कर रहा करने के लिए एक सार्वजनिक इंटरफ़ेस के बारे में सोच सकते हैं। इस संदर्भ में यदि वे उपभोक्ताओं द्वारा बुलाए जाने के तरीकों को public बनाने के लिए सही समझ में आता है; private यदि वे कक्षा में आंतरिक हैं; और package private यदि इन मॉड्यूल में कक्षाओं के बीच कॉल करने के लिए उपयोग किया जाता है, यानी यह आपके मॉड्यूल का कार्यान्वयन विवरण है (जैसा कि सार्वजनिक कॉलर्स द्वारा देखा गया है) लेकिन कई वर्गों को फैलाता है।

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

+1

मैं देख सकता हूं कि किसी ने ऐसा क्यों कहा होगा - 'संरक्षित' संशोधक 'पैकेज निजी' जैसा ही है, सिवाय इसके कि सबक्लास को पार्टी में भी आमंत्रित किया जाता है। लेकिन अगर कोई स्वाभाविक रूप से अस्तित्व में नहीं था तो उप-वर्ग संबंध बनाना (केवल पहुंच उद्देश्यों के लिए) बनाना गलत होगा। यह आमतौर पर उदाहरण के लिए कोई समझ नहीं लेता एक 'ईमेलसेन्डर' वर्ग 'DomainObjectFilter' वर्ग या इसके विपरीत के उप-वर्ग होने के लिए। इस स्थिति में विधि को आम तौर पर 'सार्वजनिक' बनाया जाता है (शायद एक टिप्पणी के साथ कि यह * अवधारणात्मक * सार्वजनिक नहीं है ...)। –

+0

"किसी दिए गए मॉड्यूल के लिए सभी कक्षाओं को बिल्कुल उसी पैकेज में डंप करें - अनावश्यक" - सही है, लेकिन मैंने पैकेज में 20-30 कक्षाओं जैसे गैर-मामूली मामलों में भी इस दृष्टिकोण का उपयोग किया है। कुछ भी बड़ा, ज़ाहिर है, refactoring की जरूरत है। –

+0

क्या आप अपनी स्रोत फ़ाइलों को एक निर्देशिका पदानुक्रम में व्यवस्थित नहीं कर सके, और फिर निर्माण के दौरान, उन्हें संकलित करने से पहले सभी निर्देशिका/पैकेज में डंप करें? इससे आपको संगठनात्मक संरचना और पैकेज निजी लाभ का लाभ मिलेगा, सही? – jrahhali

1

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

2 - डिफ़ॉल्ट (यानी सार्वजनिक/संरक्षित/निजी नहीं) निजी के समान नहीं है - यह एक चौथा राज्य है। देखें Java Access Control

3 - जब आप पुस्तकालयों को लिख रहे हैं तो यह जीवन को आसान बना सकता है कि आप नहीं चाहते कि तीसरे पक्ष अंतर्निहित कोड को कार्यान्वित करने के तरीके पर भरोसा करते हैं - आप केवल एपीआई स्वयं को सार्वजनिक करते हैं।

+0

@BZ डिफ़ॉल्ट पैकेज निजी नहीं है? –

+2

http://download.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html –

+1

@BZ जो कहा गया: यदि किसी वर्ग में कोई संशोधक नहीं है (डिफ़ॉल्ट, जिसे पैकेज-निजी भी कहा जाता है)। उत्तर के लिए धन्यवाद, शब्दावली तुच्छ है :) –

2

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

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

एक अन्य कारण यह है कि आपने इसे अक्सर नहीं देखा है, यह है कि लोग कक्षाओं को अपने जावडॉक्स से डिफ़ॉल्ट पहुंच के साथ बहिष्कृत करते हैं।

+0

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

+1

मुझे यकीन नहीं है कि आप सही हैं, लेकिन मुझे स्पष्टता के लिए प्रतिक्रिया अपडेट करने में खुशी है। – jtoberon

-1

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

9

पैकेज-प्राइवेट के बारे में एक अच्छी बात यह है कि आप उन विधियों तक पहुंच प्रदान करने के लिए इसका उपयोग कर सकते हैं जिन्हें आप व्यक्तिगत रूप से इकाई परीक्षण कक्षाओं में निजी मानते हैं। निश्चित रूप से नकारात्मकता यह है कि पैकेज में अन्य वर्ग इसे कॉल कर सकते हैं जब उन्हें वास्तव में नहीं करना चाहिए।

0

कृपया ध्यान दें कि आप केवल दो विकल्प हैं जब आप कक्षाओं के बारे में बात कर रहे हैं:

  1. सार्वजनिक कक्षाएं
  2. पैकेज निजी कक्षाएं

"निजी वर्ग" की अवधारणा को अर्थहीन है। (क्यों एक वर्ग है कि कहीं भी इस्तेमाल नहीं करने के लिए ?!)

तो अगर आप मध्यवर्ती संचालन एपीआई उपयोगकर्ताओं को दिखाई करने की जरूरत नहीं है कि के लिए एक वर्ग है आप के रूप में "निजी पैकेज" यह घोषणा करने वाले हैं

साथ ही जब आप एक ही स्रोत फ़ाइल में कई कक्षाओं को परिभाषित करते हैं, तो केवल एक वर्ग को सार्वजनिक होने की अनुमति है (इसका नाम .java फ़ाइल नाम से मेल खाता है)। यदि किसी अन्य वर्ग को एक ही फ़ाइल में परिभाषित किया गया है तो यह "पैकेज निजी" होना चाहिए।

2

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

उदाहरण के तौर पर, आप एक लाइब्रेरी को देख सकते हैं जिसे मैंने विकसित किया है। javadoc में केवल 5 इंटरफेस और 12 कक्षाएं हैं, हालांकि source code में बहुत कुछ है। लेकिन जो छिपी हुई है वह ज्यादातर आंतरिक परतें होती है जो किसी ग्राहक के लिए कोई अतिरिक्त मूल्य प्रदान नहीं करती हैं (आमतौर पर सभी सार आधार वर्ग छुपाए जाते हैं)।

जेडीके में कई उदाहरण भी हैं।

0

पैकेज-निजी पहुंच स्तर protected से अधिक प्रतिबंधित है: संरक्षित विशेषताओं और विधियों को अभी भी कक्षा को उप-वर्गीकृत करके एक्सेस किया जा सकता है। संरक्षित सदस्य (या हो सकता है) विरासत के लिए लक्षित हैं जबकि पैकेज-निजी सदस्य नहीं हैं।

पैकेज-निजी सदस्यों का अक्सर उपयोग किया जाता है ताकि पैकेज के अंदर बहुस्तरीय कक्षाएं कार्यान्वयन-विशिष्ट विशेषताएँ या (उपयोगिता) विधियों तक पहुंच सकें।

/* 
* Package private constructor which shares value array for speed. 
* this constructor is always expected to be called with share==true. 
* a separate constructor is needed because we already have a public 
* String(char[]) constructor that makes a copy of the given char[]. 
*/ 
String(char[] value, boolean share) { 
    // assert share : "unshared not supported"; 
    this.value = value; 
} 

तो java.lang पैकेज के अंदर कक्षाएं कुशलता से नए Strings बना सकते हैं अगर सामग्री पहले से ही एक char[] बिना में मौजूद है:

इस के लिए अच्छा उदाहरण String के पैकेज-निजी निर्माता और StringBuilder.value चार सरणी हैं समझौता सुरक्षा। आप इसे अपने आवेदन से नहीं कर सकते हैं क्योंकि यदि आप कर सकते हैं, तो आपके पास String की आंतरिक चार सरणी तक पहुंच (संदर्भ) होगी जो अपरिवर्तनीय है (प्रतिबिंब गिनती नहीं है!)। StringBuilder (या बल्कि AbstractStringBuilder जहां कार्यान्वयन से आता है)

में चार सरणी वर्तमान मूल्य char[] value और इस char[] getValue() को एक्सेसर विधि पकड़े भी पैकेज-निजी contentEquals(StringBuffer sb) और contentEquals(CharSequence cs) तरह String की तो विभिन्न उपयोगिता तरीकों के लिए इस का उपयोग कर सकते हैं "दुनिया" में आंतरिक चार सरणी को उजागर किए बिना दक्षता और तेज तुलना।

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