आप वास्तव में टेम्पलेट पैटर्न का उपयोग कर रहे हैं। प्रतिबिंब के साथ, इन कर सकते हैं इन सुरक्षाओं अतीत में उनके रास्ते डराने-धमकाने के लिए निर्धारित किया हैकर्स की
Access Levels
Modifier | Class | Package | Subclass | World |
--------------------------------------------------
public | Y | Y | Y | Y |
protected | Y | Y | Y | N |
no modifier | Y | Y | N | N |
private | Y | N | N | N |
लघु:
1) अपने access modifiers को समझें: दो मुख्य बातें आप बाहर के उपयोगकर्ताओं से करने के लिए "छिपाएँ" विवरण कर सकता हैं अनौपचारिक रूप से कॉलिंग विधियों से आकस्मिक कोडर रखें जो सर्वोत्तम तरीके से उनके रास्ते से बाहर रखा जाता है। कोडर इसकी सराहना करेंगे। कोई भी एक अव्यवस्थित एपीआई का उपयोग करना चाहता है।
वर्तमान में b.doWork()
protected
है। तो यह केवल main()
में दिखाई देगा यदि आपका main()
कक्षा A
(यह नहीं है) में है, subclass B
(यह नहीं है), या उसी पैकेज में (स्पष्ट नहीं है, आपने पैकेज के बारे में कोई संकेत नहीं पोस्ट किया है) आपका कोड अंदर रहता है)।
यह सवाल पूछता है, आप b.doWork()
को देखने से बचाने की कोशिश कर रहे हैं? यदि आप जो पैकेज बना रहे हैं वह केवल कुछ है जिसे आप विकसित कर रहे हैं तो यह इतना बुरा नहीं हो सकता है। यदि कई लोग इस पैकेज में कई अन्य वर्गों के साथ गड़बड़ कर रहे हैं तो यह संभावना नहीं है कि वे A
और B
कक्षाओं से घनिष्ठ परिचित होंगे। यह वह मामला है जहां आप सब कुछ लटकाना नहीं चाहते हैं जहां हर कोई इसे देख सके। यहां कक्षा और उप-वर्ग पहुंच की अनुमति केवल अच्छा होगा। लेकिन कोई संशोधक नहीं है जो पैकेज एक्सेस की अनुमति के बिना सबक्लास एक्सेस की अनुमति देता है। जब तक आप protected
उप-वर्ग कर रहे हैं, तब तक आप सबसे अच्छा कर सकते हैं। इसे ध्यान में रखते हुए, बड़ी संख्या में कक्षाओं के साथ पैकेज बनाने के लिए मत जाओ। पैकेज को तंग और केंद्रित रखें। इस तरह अधिकांश लोग पैकेज के बाहर काम करेंगे जहां चीजें अच्छी और सरल लगती हैं।
संक्षेप में, यदि आप main()
को पर कॉल करने से रोके main()
को एक अलग पैकेज में डालने से रोकना चाहते हैं।
package some.other.package
public final class Main {
...
}
2) सलाह के इस अगले टुकड़ा के मूल्य अपने वर्तमान कोड के साथ समझने के लिए है क्योंकि यह मुद्दों है कि केवल ऊपर आ जाएगा, तो अपने कोड पर विस्तार किया जाता है को हल करने के बारे में है मुश्किल हो जाएगा।
public static void main(String[] args) {
A someALikeThingy = new B(); // <-- note use of type A
someALikeThingy.work(); //The name is silly but shows we've forgotten about B
//and know it isn't really just an A :)
}
: लेकिन यह वास्तव में बारीकी से b.doWork()
What does "program to interfaces, not implementations" mean?
की तरह देख रही बातों से लोगों की रक्षा अपने कोड में इसका क्या मतलब है यह बेहतर होगा कि मुख्य इस तरह दिख रही है के विचार से जुड़ा हुआ है क्यूं कर? बनाम B
प्रकार का उपयोग कर क्या उपयोग करता है? खैर A
इंटरफ़ेस होने के करीब है। नोट, यहां मेरा मतलब यह नहीं है कि जब आप कीवर्ड interface
का उपयोग करते हैं तो आपको क्या मिलता है।मेरा मतलब है कि B
टाइप A
का एक ठोस कार्यान्वयन है और यदि मुझे B
के खिलाफ कोड लिखना नहीं है तो मैं वास्तव में नहीं जानता क्योंकि कौन जानता है कि अजीब गैर A
चीजें B
है। यहां समझना मुश्किल है क्योंकि मुख्य में कोड & मीठा छोटा है। इसके अलावा, इंटरफेसA
और B
सभी अलग नहीं हैं। उनके पास केवल एक सार्वजनिक विधि work()
है। कल्पना करें कि main()
लंबा और दृढ़ था, कल्पना कीजिए B
में सभी प्रकार के गैर A
विधियां लटक रही थीं। अब कल्पना करें कि आपको कक्षा C
बनाने की आवश्यकता है जिसे आप मुख्य रूप से निपटाना चाहते हैं। यह देखने में सांत्वना नहीं होगी कि मुख्य को B
खिलाया गया था, जहां तक मुख्य रूप से प्रत्येक पंक्ति को पता है कि B
कुछ साधारण A
चीज़ की तरह है। new
के बाद भाग के अलावा यह सच हो सकता है और आपको main()
पर कुछ भी करने से बचा सकता है लेकिन new
अपडेट कर रहा है। दरअसल, ऐसा नहीं है कि दृढ़ता से टाइप की गई भाषा का उपयोग क्यों कभी-कभी अच्छा हो सकता है?
< शेख़ी >
तुम भी B()
साथ new
के बाद वह हिस्सा अद्यतन करने लगता है कि अगर बहुत ज्यादा काम तुम अकेले नहीं हो रहा है। उस विशेष छोटे जुनून ने हमें dependency injection movement दिया है जो ढांचे का एक गुच्छा पैदा करता है जो एक साधारण इंजेक्शन की तुलना में ऑब्जेक्ट निर्माण को स्वचालित करने के बारे में वास्तव में अधिक था जो कि कोई भी कन्स्ट्रक्टर आपको करने दे सकता है।
</शेख़ी >
अद्यतन:
मैं अपनी टिप्पणी है कि आप छोटे तंग संकुल बनाने के लिए अनिच्छुक रहे हैं से देखते हैं। उस मामले में एक रचना आधारित रणनीति पैटर्न के पक्ष में विरासत आधारित टेम्पलेट पैटर्न को छोड़ने पर विचार करें। आप अभी भी बहुरूपता प्राप्त करते हैं। यह सिर्फ मुफ्त में नहीं होता है। थोड़ा अधिक कोड लेखन और संकेत। लेकिन आप रन टाइम पर भी राज्य बदल सकते हैं।
यह काउंटर अंतर्ज्ञानी प्रतीत होगा क्योंकि अब doWork()
सार्वजनिक होना चाहिए। वह किस तरह की सुरक्षा है? अब आप B
पूरी तरह से पीछे या यहां तक कि AHandler
के अंदर भी छिपा सकते हैं। यह कुछ मानव अनुकूल मुखौटा वर्ग है जो आपके टेम्पलेट कोड का उपयोग करता है लेकिन केवल work()
का खुलासा करता है। A
सिर्फ interface
हो सकता है ताकि AHandler
अभी भी पता नहीं है कि इसमें B
है। यह दृष्टिकोण निर्भरता इंजेक्शन भीड़ के साथ लोकप्रिय है लेकिन निश्चित रूप से सार्वभौमिक अपील नहीं है। कुछ लोग इसे हर बार अंधा करते हैं जो कई को परेशान करता है। आप यहाँ इसके बारे में अधिक पढ़ सकते हैं: Prefer composition over inheritance?
"एक आसानी से गलती से b.doWork फोन करने में सक्षम है()"। वास्तव में? यह संरक्षित है, इसलिए केवल ए या बी उदाहरण इसे कॉल कर सकते हैं। –
दुर्भाग्यवश, चूंकि यह संरक्षित है, पैकेज से सभी वर्ग इसे कॉल कर सकते हैं। विभाजन पैकेज एक तरीका है, हालांकि मैं 1- या 2-वर्ग पैकेज होने से बचाना चाहता हूं। –
नहीं !! आप डिफ़ॉल्ट एक्सेस संशोधक का वर्णन कर रहे हैं (यानी कोई नहीं)। संरक्षित मतलब है "केवल मुझे या कक्षाएं जो मुझे विस्तारित करती हैं, इसका उपयोग इस" –