जावा में एक आंतरिक वर्ग और एक स्थिर नेस्टेड वर्ग के बीच मुख्य अंतर क्या है? क्या डिजाइन / कार्यान्वयन इनमें से किसी एक को चुनने में भूमिका निभाता है?
जावा में एक आंतरिक वर्ग और एक स्थिर नेस्टेड वर्ग के बीच मुख्य अंतर क्या है? क्या डिजाइन / कार्यान्वयन इनमें से किसी एक को चुनने में भूमिका निभाता है?
जवाबों:
से जावा ट्यूटोरियल :
नेस्टेड वर्गों को दो श्रेणियों में विभाजित किया जाता है: स्थिर और गैर-स्थिर। नीडिंत कक्षाएं जिन्हें स्टैटिक घोषित किया जाता है, बस स्टैटिक नेस्टेड क्लासेस कहलाती हैं। नॉन-स्टैटिक नेस्टेड क्लासेस को इनर क्लास कहा जाता है।
स्टैटिक नेस्टेड क्लासेस एंक्लोज़िंग क्लास नाम का उपयोग करके एक्सेस किए जाते हैं:
OuterClass.StaticNestedClass
उदाहरण के लिए, स्थिर नेस्टेड क्लास के लिए ऑब्जेक्ट बनाने के लिए, इस सिंटैक्स का उपयोग करें:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
बाहरी वर्ग के उदाहरण के भीतर एक आंतरिक वर्ग के उदाहरण हैं। निम्नलिखित वर्गों पर विचार करें:
class OuterClass {
...
class InnerClass {
...
}
}
इनरक्लास का एक उदाहरण केवल आउटरक्लास के एक उदाहरण के भीतर मौजूद हो सकता है और इसके संलग्न उदाहरण के तरीकों और क्षेत्रों तक सीधी पहुंच है।
एक आंतरिक कक्षा को तुरंत करने के लिए, आपको सबसे पहले बाहरी कक्षा को तुरंत बदलना होगा। फिर, इस सिंटैक्स के साथ बाहरी ऑब्जेक्ट के भीतर आंतरिक ऑब्जेक्ट बनाएं:
OuterClass outerObject = new OuterClass()
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
देखें: जावा ट्यूटोरियल - नेस्टेड क्लासेस
पूर्णता के लिए ध्यान दें कि एक आंतरिक वर्ग के रूप में एक ऐसी चीज भी है जो बिना संलग्नक उदाहरण के है :
class A {
int t() { return 1; }
static A a = new A() { int t() { return 2; } };
}
यहां, new A() { ... }
एक आंतरिक वर्ग को एक स्थिर संदर्भ में परिभाषित किया गया है और इसमें एक संलग्न उदाहरण नहीं है।
import OuterClass.StaticNestedClass;
फिर क्लास को केवल आउटरक्लास के रूप में देखें।
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
?
शब्दावली: नेस्टेड वर्गों को दो श्रेणियों में विभाजित किया जाता है: स्थिर और गैर-स्थिर। नीडिंत कक्षाएं जिन्हें स्टैटिक घोषित किया जाता है, बस स्टैटिक नेस्टेड क्लासेस कहलाती हैं। नॉन-स्टैटिक नेस्टेड क्लासेस को इनर क्लास कहा जाता है।
आम बोलचाल में, अधिकांश प्रोग्रामर द्वारा "नेस्टेड" और "इनर" शब्दों का परस्पर उपयोग किया जाता है, लेकिन मैं सही शब्द "नेस्टेड क्लास" का उपयोग करूंगा, जो आंतरिक और स्थिर दोनों को कवर करता है।
कक्षाओं को नेस्टेड इनफिनिटम कहा जा सकता है , जैसे क्लास ए में क्लास बी हो सकता है जिसमें क्लास सी होता है जिसमें क्लास डी होता है, आदि। हालांकि, क्लास नेस्टिंग का एक से अधिक स्तर दुर्लभ है, क्योंकि यह आमतौर पर खराब डिजाइन है।
एक नेस्टेड क्लास बनाने के तीन कारण हैं:
कर रहे हैं जावा में नेस्टेड वर्ग के चार प्रकार । संक्षेप में, वे हैं:
मुझे और अधिक विवरण में बताएं।
स्टैटिक क्लास समझने के लिए सबसे आसान तरीका है क्योंकि उन्हें क्लास वाले इंस्टैंस से कोई लेना-देना नहीं है।
एक स्थिर वर्ग एक वर्ग है जिसे दूसरे वर्ग के स्थिर सदस्य के रूप में घोषित किया जाता है। बस अन्य स्थिर सदस्यों की तरह, इस तरह के एक वर्ग वास्तव में सिर्फ इतना है कि का उपयोग करता है अपने नाम स्थान, के रूप में युक्त वर्ग पर एक हैंगर है जैसे वर्ग बकरी वर्ग के एक स्थिर सदस्य के रूप में घोषित राइनो पैकेज में पिज्जा नाम से जाना जाता है pizza.Rhino.Goat ।
package pizza;
public class Rhino {
...
public static class Goat {
...
}
}
सच कहूँ तो, स्थिर वर्ग एक बहुत ही बेकार विशेषता है क्योंकि कक्षाएं पहले से ही संकुल द्वारा नाम स्थान में विभाजित हैं। स्टैटिक क्लास बनाने का एकमात्र वास्तविक बोधगम्य कारण यह है कि इस तरह की क्लास की अपनी क्लास के प्राइवेट स्टैटिक सदस्यों तक पहुँच होती है, लेकिन मुझे लगता है कि स्टैटिक क्लास फ़ीचर के अस्तित्व के लिए यह एक बहुत ही अच्छा औचित्य है।
एक आंतरिक वर्ग एक ऐसा वर्ग है जिसे दूसरे वर्ग का गैर-स्थैतिक सदस्य घोषित किया जाता है:
package pizza;
public class Rhino {
public class Goat {
...
}
private void jerry() {
Goat g = new Goat();
}
}
स्टैटिक क्लास की तरह, इनर क्लास को उसके क्लास नाम, पिज्जा.हिनो.गुआट द्वारा क्वालिफाइड के रूप में जाना जाता है , लेकिन इसमें मौजूद क्लास के अंदर इसे सिंपल नाम से जाना जा सकता है। हालाँकि, एक आंतरिक वर्ग का प्रत्येक उदाहरण अपनी युक्त वर्ग के एक विशेष उदाहरण से जुड़ा होता है: ऊपर, गोरी इन जेरी में बनाया गया है , यह स्पष्ट रूप से राइनो उदाहरण के लिए इसे जेरी में बांधा गया है । अन्यथा, हम बकरी को पलटने पर संबंधित राइनो उदाहरण को स्पष्ट करते हैं :
Rhino rhino = new Rhino();
Rhino.Goat goat = rhino.new Goat();
(ध्यान दें कि आप नए प्रकार के अजीब नए वाक्यविन्यास में केवल बकरी के रूप में आंतरिक प्रकार का उल्लेख करते हैं : जावा राइनो भाग से युक्त प्रकार को संक्रमित करता है । और, हाँ नया राइनो.गायट () मेरे लिए भी अधिक समझ में आता है।)
तो इससे हमें क्या हासिल होता है? ठीक है, आंतरिक वर्ग उदाहरण में वर्ग श्रेणी के उदाहरण के सदस्यों की पहुंच है। ये संलग्न उदाहरण सदस्यों भीतरी वर्ग के अंदर में भेजा जाता है के माध्यम से , सिर्फ अपने साधारण नाम नहीं के माध्यम से इस ( इस भीतरी कक्षा में भीतरी वर्ग उदाहरण के लिए, नहीं जुड़े युक्त वर्ग उदाहरण के लिए संदर्भित करता है):
public class Rhino {
private String barry;
public class Goat {
public void colin() {
System.out.println(barry);
}
}
}
भीतरी वर्ग में, आप का उल्लेख कर सकते इस रूप में युक्त वर्ग के Rhino.this , और आप उपयोग कर सकते हैं इस अपने सदस्यों, का उल्लेख करने जैसे Rhino.this.barry ।
एक स्थानीय आंतरिक वर्ग एक विधि के शरीर में घोषित एक वर्ग है। इस तरह के एक वर्ग को केवल इसकी युक्त पद्धति के भीतर जाना जाता है, इसलिए इसे केवल त्वरित किया जा सकता है और इसके सदस्यों को इसकी विधि के भीतर पहुँचा जा सकता है। लाभ यह है कि एक स्थानीय आंतरिक वर्ग उदाहरण से जुड़ा हुआ है और इसके युक्त विधि के अंतिम स्थानीय चर तक पहुंच सकता है। जब उदाहरण अपनी युक्त विधि का एक अंतिम स्थानीय उपयोग करता है, तो चर उदाहरण के निर्माण के समय आयोजित मूल्य को बरकरार रखता है, भले ही चर दायरे से बाहर हो गया हो (यह प्रभावी रूप से जावा का कच्चा, बंद संस्करण का सीमित संस्करण है)।
क्योंकि एक स्थानीय आंतरिक वर्ग न तो किसी वर्ग या पैकेज का सदस्य होता है, न ही इसे एक्सेस स्तर के साथ घोषित किया जाता है। (स्पष्ट रहें, हालांकि, इसके अपने सदस्यों के पास एक सामान्य वर्ग की तरह पहुंच स्तर है।)
यदि किसी स्थानीय आंतरिक वर्ग को उदाहरण विधि में घोषित किया जाता है, तो आंतरिक वर्ग का एक तात्कालिक उदाहरण इंस्टेंस के निर्माण के समय में इस विधि द्वारा आयोजित उदाहरण से जुड़ा होता है , और इसलिए वर्ग के आवृत्ति सदस्य उदाहरण में सुलभ होते हैं भीतरी वर्ग। एक स्थानीय आंतरिक वर्ग को उसके नाम के माध्यम से तत्काल रूप से बदल दिया जाता है, जैसे स्थानीय आंतरिक वर्ग कैट को नई बिल्ली () के रूप में त्वरित किया जाता है, नया नहीं। यह () जैसा कि आप उम्मीद कर सकते हैं।
एक अनाम आंतरिक वर्ग एक स्थानीय आंतरिक वर्ग लिखने का एक सहज सुविधाजनक तरीका है। सबसे आम तौर पर, एक स्थानीय आंतरिक वर्ग को हर बार एक ही बार में चलाया जाता है, जब हर बार इसकी विधि को चलाया जाता है। यह अच्छा होगा, फिर, अगर हम स्थानीय आंतरिक वर्ग की परिभाषा और इसकी एकल संकेंद्रण को एक सुविधाजनक वाक्यविन्यास रूप में जोड़ सकते हैं, और यह भी अच्छा होगा यदि हमें कक्षा के लिए एक नाम नहीं सोचना चाहिए (कम अनपेक्षित आपके कोड में नाम शामिल हैं, बेहतर)। एक अनाम आंतरिक वर्ग इन दोनों चीजों की अनुमति देता है:
new *ParentClassName*(*constructorArgs*) {*members*}
यह एक अनाम वर्ग का एक नया उदाहरण लौटाने वाली एक अभिव्यक्ति है जो ParentClassName का विस्तार करता है । आप अपने स्वयं के निर्माता की आपूर्ति नहीं कर सकते; इसके बजाय, एक को कथित रूप से आपूर्ति की जाती है जो बस सुपर कंस्ट्रक्टर को बुलाता है, इसलिए आपूर्ति की गई दलीलें सुपर कंस्ट्रक्टर को फिट करनी चाहिए। (यदि माता-पिता में कई निर्माता होते हैं, तो "सबसे सरल" एक कहा जाता है, "सरलतम" जैसा कि नियमों के एक जटिल परिसर द्वारा निर्धारित किया गया है, जो विस्तार से जानने के लिए परेशान करने लायक नहीं है - बस उस पर ध्यान दें जो NetBeans या ग्रहण आपको बताते हैं।)
वैकल्पिक रूप से, आप एक इंटरफ़ेस को लागू करने के लिए निर्दिष्ट कर सकते हैं:
new *InterfaceName*() {*members*}
इस तरह की घोषणा से अनाम वर्ग का एक नया उदाहरण बनता है, जो ऑब्जेक्ट को लागू करता है और इंटरफ़ेसनाम को लागू करता है । फिर, आप अपने स्वयं के निर्माता की आपूर्ति नहीं कर सकते; इस मामले में, जावा स्पष्ट रूप से नो-आर्ग, डू-नथिंग कंस्ट्रक्टर की आपूर्ति करता है (इसलिए इस मामले में कंस्ट्रक्टर के तर्क कभी नहीं होंगे)।
भले ही आप एक अनाम आंतरिक वर्ग को एक निर्माता नहीं दे सकते हैं, फिर भी आप किसी भी सेटअप को एक शुरुआती ब्लॉक (किसी विधि के बाहर रखा गया {{} ब्लॉक) का उपयोग करके कर सकते हैं।
स्पष्ट रहें कि एक गुमनाम आंतरिक वर्ग एक उदाहरण के साथ स्थानीय आंतरिक वर्ग बनाने का एक कम लचीला तरीका है। यदि आप एक स्थानीय आंतरिक वर्ग चाहते हैं जो कई इंटरफेसों को लागू करता है या जो ऑब्जेक्ट के अलावा किसी अन्य वर्ग का विस्तार करते हुए इंटरफेस को लागू करता है या जो अपने स्वयं के निर्माता को निर्दिष्ट करता है, तो आप एक नियमित नाम के आंतरिक वर्ग का निर्माण करते हुए अटक जाते हैं।
मुझे नहीं लगता कि उपरोक्त उत्तरों में वास्तविक अंतर स्पष्ट हो गया है।
शर्तें सही पाने के लिए सबसे पहले:
मार्टिन का जवाब अभी तक सही है। हालाँकि, वास्तविक प्रश्न यह है: नेस्टेड क्लास को स्थिर घोषित करने का उद्देश्य क्या है या नहीं?
यदि आप अपनी कक्षाओं को एक साथ रखना चाहते हैं, तो यदि वे टॉपिक रूप से एक साथ हैं या यदि नेस्टेड क्लास में नेस्टेड क्लास का उपयोग किया जाता है, तो आप स्थिर नेस्टेड कक्षाओं का उपयोग करते हैं। स्टैटिक नेस्टेड क्लास और हर दूसरे वर्ग के बीच कोई शब्दार्थ अंतर नहीं होता है।
गैर-स्थैतिक नेस्टेड कक्षाएं एक अलग जानवर हैं। अनाम आंतरिक वर्गों के समान, ऐसे नेस्टेड वर्ग वास्तव में बंद होते हैं। इसका मतलब है कि वे अपने आस-पास के दायरे और उनके संलग्न उदाहरण को पकड़ते हैं और उस सुलभ को बनाते हैं। शायद एक उदाहरण स्पष्ट करेगा। देखें कंटेनर का यह ठूंठ:
public class Container {
public class Item{
Object data;
public Container getContainer(){
return Container.this;
}
public Item(Object data) {
super();
this.data = data;
}
}
public static Item create(Object data){
// does not compile since no instance of Container is available
return new Item(data);
}
public Item createSubItem(Object data){
// compiles, since 'this' Container is available
return new Item(data);
}
}
इस स्थिति में आप चाइल्ड आइटम से पैरेंट कंटेनर तक का संदर्भ लेना चाहते हैं। एक गैर-स्थिर नेस्टेड वर्ग का उपयोग करना, यह कुछ काम के बिना काम करता है। आप सिंटैक्स के साथ कंटेनर के संलग्न उदाहरण का उपयोग कर सकते हैं Container.this
।
अधिक कट्टर स्पष्टीकरण निम्नलिखित हैं:
यदि आप जावा बाइटकोड को देखते हैं तो संकलक एक (गैर-स्थिर) नेस्टेड वर्ग के लिए उत्पन्न होता है, यह और भी स्पष्ट हो सकता है:
// class version 49.0 (49)
// access flags 33
public class Container$Item {
// compiled from: Container.java
// access flags 1
public INNERCLASS Container$Item Container Item
// access flags 0
Object data
// access flags 4112
final Container this$0
// access flags 1
public getContainer() : Container
L0
LINENUMBER 7 L0
ALOAD 0: this
GETFIELD Container$Item.this$0 : Container
ARETURN
L1
LOCALVARIABLE this Container$Item L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 1
public <init>(Container,Object) : void
L0
LINENUMBER 12 L0
ALOAD 0: this
ALOAD 1
PUTFIELD Container$Item.this$0 : Container
L1
LINENUMBER 10 L1
ALOAD 0: this
INVOKESPECIAL Object.<init>() : void
L2
LINENUMBER 11 L2
ALOAD 0: this
ALOAD 2: data
PUTFIELD Container$Item.data : Object
RETURN
L3
LOCALVARIABLE this Container$Item L0 L3 0
LOCALVARIABLE data Object L0 L3 2
MAXSTACK = 2
MAXLOCALS = 3
}
जैसा कि आप देख सकते हैं संकलक एक छिपे हुए क्षेत्र बनाता है Container this$0
। यह कंस्ट्रक्टर में सेट किया गया है जिसमें एन्कोडिंग इंस्टेंस निर्दिष्ट करने के लिए कंटेनर का एक अतिरिक्त पैरामीटर है। आप इस पैरामीटर को स्रोत में नहीं देख सकते हैं लेकिन संकलक निहित रूप से इसे नेस्टेड वर्ग के लिए उत्पन्न करता है।
मार्टिन का उदाहरण
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
ऐसा कुछ कॉल करने के लिए संकलित किया जाएगा जैसे (bytecodes में)
new InnerClass(outerObject)
परिपूर्णता के लिए:
एक अनाम वर्ग एक गैर-स्थिर नेस्टेड वर्ग का एक आदर्श उदाहरण है, जिसका अभी कोई नाम नहीं जुड़ा है और बाद में इसे संदर्भित नहीं किया जा सकता है।
मुझे लगता है कि उपर्युक्त उत्तरों में से कोई भी आपको नेस्टेड क्लास और एप्लिकेशन डिज़ाइन की अवधि में एक स्थिर नेस्टेड क्लास के बीच वास्तविक अंतर नहीं समझाता है:
एक नेस्टेड वर्ग गैर-स्थिर या स्थिर हो सकता है और प्रत्येक मामले में एक वर्ग दूसरे वर्ग के भीतर परिभाषित होता है । एक नेस्टेड वर्ग केवल सेवा करने के लिए मौजूद होना चाहिए , यदि एनस्टेड क्लास अन्य वर्गों (न केवल एनक्लोजिंग) द्वारा उपयोगी है, तो उसे शीर्ष स्तर के वर्ग के रूप में घोषित किया जाना चाहिए।
नॉनस्टैटिक नेस्टेड क्लास : अंतर्निहित रूप से संबंधित वर्ग के संलग्न उदाहरण के साथ जुड़ा हुआ है, इसका मतलब यह है कि एनकोडिंग इंस्टेंस के तरीकों और एक्सेस चर को प्राप्त करना संभव है। नॉनस्टैटिक नेस्टेड क्लास का एक सामान्य उपयोग एडेप्टर क्लास को परिभाषित करना है।
स्टेटिक नेस्टेड क्लास : एनक्लोजिंग क्लास का उपयोग नहीं कर सकते हैं और उस पर तरीकों का आह्वान कर सकते हैं, इसलिए इसका उपयोग तब किया जाना चाहिए जब नेस्टेड क्लास को एन्क्लोजिंग क्लास के इंस्टेंस तक पहुंच की आवश्यकता न हो। स्टैटिक नेस्टेड क्लास का एक सामान्य उपयोग बाहरी वस्तु के घटकों को लागू करना है।
तो एक डिजाइन दृष्टिकोण से दोनों के बीच मुख्य अंतर यह है: नॉनस्टैटिक नेस्टेड क्लास कंटेनर वर्ग के उदाहरण तक पहुंच सकता है, जबकि स्थिर नहीं हो सकता है ।
सरल शब्दों में, हमें मुख्य रूप से नेस्टेड वर्गों की आवश्यकता है क्योंकि जावा क्लोजर प्रदान नहीं करता है।
नेस्टेड क्लासेस एक अन्य संलग्न वर्ग के शरीर के अंदर परिभाषित कक्षाएं हैं। वे दो प्रकार के होते हैं- स्टेटिक और नॉन-स्टैटिक।
उन्हें एन्क्लोज़िंग क्लास के सदस्यों के रूप में माना जाता है, इसलिए आप किसी भी चार एक्सेस स्पेसियर को निर्दिष्ट कर सकते हैं - private, package, protected, public
। हमारे पास शीर्ष स्तर की कक्षाओं के साथ यह लक्जरी नहीं है, जिसे केवल घोषित public
या पैकेज-निजी किया जा सकता है ।
इनर क्लासेस उर्फ नॉन-स्टैक क्लासेस की टॉप क्लास के अन्य सदस्यों तक पहुंच होती है, भले ही उन्हें निजी घोषित किया गया हो, जबकि स्टेटिक नेस्टेड क्लासेस में टॉप क्लास के अन्य सदस्यों तक पहुंच नहीं होती है।
public class OuterClass {
public static class Inner1 {
}
public class Inner2 {
}
}
Inner1
हमारा स्थिर आंतरिक वर्ग है और Inner2
हमारा आंतरिक वर्ग है जो स्थिर नहीं है। उनके बीच महत्वपूर्ण अंतर, आप Inner2
एक बाहरी के बिना एक उदाहरण नहीं बना सकते हैं जहां आप Inner1
स्वतंत्र रूप से एक ऑब्जेक्ट बना सकते हैं ।
आप इनर क्लास का उपयोग कब करेंगे?
ऐसी स्थिति के बारे में सोचें जहां से संबंधित हैं Class A
और सदस्यों तक पहुंचने की आवश्यकता है , और केवल उसी से संबंधित है । भीतरी वर्ग चित्र में आता है।Class B
Class B
Class A
Class B
Class A
आंतरिक वर्ग का एक उदाहरण बनाने के लिए, आपको अपने बाहरी वर्ग का एक उदाहरण बनाने की आवश्यकता है।
OuterClass outer = new OuterClass();
OuterClass.Inner2 inner = outer.new Inner2();
या
OuterClass.Inner2 inner = new OuterClass().new Inner2();
आप स्टेटिक इनर क्लास का उपयोग कब करेंगे?
आप एक स्थिर आंतरिक वर्ग को परिभाषित करते हैं जब आप जानते हैं कि इसका संलग्न वर्ग / शीर्ष वर्ग के उदाहरण के साथ कोई संबंध नहीं है। यदि आपका आंतरिक वर्ग बाहरी वर्ग के तरीकों या क्षेत्रों का उपयोग नहीं करता है, तो यह केवल अंतरिक्ष की बर्बादी है, इसलिए इसे स्थिर बनाएं।
उदाहरण के लिए, स्थिर नेस्टेड क्लास के लिए ऑब्जेक्ट बनाने के लिए, इस सिंटैक्स का उपयोग करें:
OuterClass.Inner1 nestedObject = new OuterClass.Inner1();
स्टैटिक नेस्टेड क्लास का लाभ यह है कि इसमें काम करने के लिए क्लास / टॉप क्लास वाली वस्तु की आवश्यकता नहीं होती है। यह आपके द्वारा रनटाइम पर आपके द्वारा बनाई गई वस्तुओं की संख्या को कम करने में आपकी सहायता कर सकता है।
OuterClass.Inner2 inner = outer.new Inner2();
?
static inner
शब्दों में एक विरोधाभास है।
यहाँ जावा आंतरिक वर्ग और स्थिर नेस्टेड वर्ग के बीच महत्वपूर्ण अंतर और समानताएं हैं।
आशा है ये मदद करेगा!
संलग्न वर्ग के उदाहरण के साथ संबद्ध करने के लिए इसे तुरंत करने के लिए पहले बाहरी वर्ग ( नए कीवर्ड स्थान पर ध्यान दें ) का उदाहरण चाहिए :
Outerclass.InnerClass innerObject = outerObject.new Innerclass();
किसी भी स्थिर सदस्य को स्वयं परिभाषित नहीं किया जा सकता है
बाहरी वर्ग उदाहरण विधियों या फ़ील्ड तक नहीं पहुँच सकता
संलग्न करने के लिए वर्ग के किसी भी उदाहरण के साथ जुड़ा नहीं है ताकि इसे तुरंत किया जा सके:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
Oracle प्रलेखन के अनुसार कई कारण हैं ( पूर्ण प्रलेखन ):
यह तार्किक रूप से समूहन वर्गों का एक तरीका है जो केवल एक ही स्थान पर उपयोग किया जाता है: यदि कोई वर्ग केवल एक अन्य वर्ग के लिए उपयोगी है, तो उसे उस कक्षा में एम्बेड करना और दोनों को एक साथ रखना तर्कसंगत है। ऐसे "हेल्पर वर्गों" को घोंसले बनाने से उनके पैकेज को अधिक सुव्यवस्थित किया जाता है।
यह एन्कैप्सुलेशन को बढ़ाता है: दो शीर्ष-स्तरीय कक्षाओं, ए और बी पर विचार करें, जहां बी को ए के सदस्यों तक पहुंच की आवश्यकता है जो अन्यथा निजी घोषित किए जाएंगे। कक्षा बी को कक्षा ए के भीतर छिपाकर, ए के सदस्यों को निजी घोषित किया जा सकता है और बी उन्हें एक्सेस कर सकते हैं। इसके अलावा, बी खुद को बाहरी दुनिया से छिपाया जा सकता है।
यह अधिक पठनीय और बनाए रखने योग्य कोड को जन्म दे सकता है: शीर्ष स्तर की कक्षाओं के भीतर छोटी कक्षाओं को घोंसले में रखना कोड को उस स्थान के करीब रखता है जहां इसका उपयोग किया जाता है।
मुझे लगता है, आम तौर पर पालन किया जाने वाला सम्मेलन यह है:
हालाँकि, याद करने के लिए कुछ अन्य बिंदु हैं:
शीर्ष स्तर की कक्षाएं और स्टैटिक नेस्टेड क्लास शब्दशः समान होते हैं सिवाय इसके कि स्टैटिक नेस्टेड क्लास के मामले में यह निजी स्टेटिक फील्ड्स / अपने बाहरी [पैरेंट] क्लास के तरीकों और इसके विपरीत स्टेटिक रेफरेंस बना सकता है।
आंतरिक कक्षाओं में बाहरी [मूल] वर्ग के संलग्न उदाहरण के चर का उपयोग होता है। हालाँकि, सभी आंतरिक वर्गों के पास उदाहरण नहीं हैं, उदाहरण के लिए स्थैतिक संदर्भों में आंतरिक कक्षाएं, एक स्थिर प्रारंभिक ब्लॉक में प्रयुक्त अनाम वर्ग की तरह, नहीं।
डिफ़ॉल्ट रूप से अनाम वर्ग मूल वर्ग को बढ़ाता है या मूल इंटरफ़ेस को लागू करता है और किसी भी अन्य वर्ग का विस्तार करने या किसी भी अधिक इंटरफेस को लागू करने के लिए आगे कोई खंड नहीं है। इसलिए,
new YourClass(){};
माध्यम class [Anonymous] extends YourClass {}
new YourInterface(){};
माध्यम class [Anonymous] implements YourInterface {}
मुझे लगता है कि बड़ा सवाल जो खुला रहता है वह कौन सा उपयोग करना है और कब? वैसे यह ज्यादातर इस बात पर निर्भर करता है कि आप किस परिदृश्य से निपट रहे हैं लेकिन @jrudolph द्वारा दिए गए उत्तर को पढ़ने से आपको कुछ निर्णय लेने में मदद मिल सकती है।
नेस्टेड क्लास: क्लास के अंदर क्लास
प्रकार:
अंतर:
नॉन-स्टैटिक नेस्टेड क्लास [इनर क्लास]
बाहरी वर्ग की वस्तु के भीतर आंतरिक वर्ग के गैर-स्थिर नेस्टेड क्लास ऑब्जेक्ट मौजूद हैं। ताकि बाहरी वर्ग का डेटा सदस्य आंतरिक वर्ग के लिए सुलभ हो। इसलिए आंतरिक वर्ग की वस्तु बनाने के लिए हमें पहले बाहरी वर्ग की वस्तु बनानी होगी।
outerclass outerobject=new outerobject();
outerclass.innerclass innerobjcet=outerobject.new innerclass();
स्टेटिक नेस्टेड क्लास
आंतरिक वर्ग के स्थिर नेस्टेड क्लास ऑब्जेक्ट में बाहरी वर्ग की वस्तु की आवश्यकता नहीं होती है, क्योंकि "स्थिर" शब्द से ऑब्जेक्ट बनाने की कोई आवश्यकता नहीं है।
class outerclass A {
static class nestedclass B {
static int x = 10;
}
}
यदि आप x तक पहुँचना चाहते हैं, तो अंदर की विधि लिखिए
outerclass.nestedclass.x; i.e. System.out.prinltn( outerclass.nestedclass.x);
आंतरिक वर्ग का उदाहरण तब बनता है जब बाहरी वर्ग का उदाहरण बनाया जाता है। इसलिए आंतरिक वर्ग के सदस्यों और तरीकों का बाहरी वर्ग के उदाहरण (ऑब्जेक्ट) के सदस्यों और तरीकों तक पहुंच है। जब बाहरी वर्ग का उदाहरण कार्यक्षेत्र से बाहर हो जाता है, तब भी आंतरिक वर्ग का अस्तित्व समाप्त हो जाता है।
स्थिर नेस्टेड वर्ग में एक ठोस उदाहरण नहीं है। जब यह पहली बार उपयोग किया जाता है तो इसे लोड किया जाता है (स्थिर तरीकों की तरह)। यह पूरी तरह से स्वतंत्र इकाई है, जिसके तरीकों और चर में बाहरी वर्ग के उदाहरणों तक कोई पहुंच नहीं है।
स्थिर नेस्टेड कक्षाएं बाहरी ऑब्जेक्ट के साथ युग्मित नहीं होती हैं, वे तेज होती हैं, और वे ढेर / स्टैक मेमोरी नहीं लेते हैं, क्योंकि इस तरह के वर्ग का उदाहरण बनाना आवश्यक नहीं है। इसलिए अंगूठे का नियम स्थिर नेस्टेड क्लास को परिभाषित करने की कोशिश करना है, संभव के रूप में सीमित दायरे के साथ (निजी> = वर्ग> = संरक्षित> = सार्वजनिक), और फिर इसे आंतरिक वर्ग ("स्थिर" पहचानकर्ता को हटाकर) और ढीले में परिवर्तित करें गुंजाइश, अगर यह वास्तव में आवश्यक है।
नेस्टेड स्टैटिक वर्गों के उपयोग के बारे में एक सूक्ष्मता है जो कुछ स्थितियों में उपयोगी हो सकती है।
जबकि स्थिर विशेषताओं को उसके निर्माता के माध्यम से तत्काल प्राप्त होने से पहले त्वरित प्राप्त हो जाता है, नेस्टेड स्थिर वर्गों के अंदर स्थिर विशेषताओं को तब तक त्वरित रूप से प्राप्त नहीं किया जाता है जब तक कि वर्ग के निर्माता के आह्वान होने के बाद, या कम से कम तब तक न हो जब तक कि विशेषताओं को पहले से निर्धारित नहीं किया जाता है, भले ही उन्हें 'अंतिम' के रूप में चिह्नित किया गया है।
इस उदाहरण पर विचार करें:
public class C0 {
static C0 instance = null;
// Uncomment the following line and a null pointer exception will be
// generated before anything gets printed.
//public static final String outerItem = instance.makeString(98.6);
public C0() {
instance = this;
}
public String makeString(int i) {
return ((new Integer(i)).toString());
}
public String makeString(double d) {
return ((new Double(d)).toString());
}
public static final class nested {
public static final String innerItem = instance.makeString(42);
}
static public void main(String[] argv) {
System.out.println("start");
// Comment out this line and a null pointer exception will be
// generated after "start" prints and before the following
// try/catch block even gets entered.
new C0();
try {
System.out.println("retrieve item: " + nested.innerItem);
}
catch (Exception e) {
System.out.println("failed to retrieve item: " + e.toString());
}
System.out.println("finish");
}
}
भले ही 'नेस्टेड' और 'इनरएटइम' दोनों को 'स्टैटिक फाइनल' घोषित किया गया हो। nested.innerItem की स्थापना तब तक नहीं होती है, जब तक कि क्लास तुरंत होने के बाद (या कम से कम तब तक न हो जब तक नेस्टेड स्टैटिक आइटम को पहली बार संदर्भित नहीं किया जाता है), जैसा कि आप मेरे द्वारा देखी गई लाइनों को कमेंट करके और अनसुना करके अपने लिए देख सकते हैं। ऊपर। वही 'आउटरइम' के लिए सही नहीं है।
कम से कम यह मैं जावा 6.0 में देख रहा हूं।
शब्दों का प्रयोग परस्पर किया जाता है। यदि आप इसके बारे में वास्तव में पांडित्यपूर्ण होना चाहते हैं, तो आप एक स्थिर आंतरिक वर्ग को संदर्भित करने के लिए "नेस्टेड क्लास" को परिभाषित कर सकते हैं, जिसमें कोई संलग्न उदाहरण नहीं है। कोड में, आपके पास कुछ इस तरह हो सकता है:
public class Outer {
public class Inner {}
public static class Nested {}
}
हालांकि यह वास्तव में एक व्यापक रूप से स्वीकृत परिभाषा नहीं है।
उदाहरण बनाने के मामले में, गैर स्थिर आंतरिक वर्ग का उदाहरण बाहरी वर्ग के ऑब्जेक्ट के संदर्भ के साथ बनाया गया है जिसमें यह परिभाषित किया गया है। इसका मतलब यह है कि यह उदाहरण है। लेकिन स्थिर आंतरिक वर्ग का उदाहरण बाहरी वर्ग के संदर्भ के साथ बनाया जाता है, बाहरी वर्ग की वस्तु के संदर्भ से नहीं। इसका मतलब है कि इसका उदाहरण नहीं है।
उदाहरण के लिए:
class A
{
class B
{
// static int x; not allowed here…..
}
static class C
{
static int x; // allowed here
}
}
class Test
{
public static void main(String… str)
{
A o=new A();
A.B obj1 =o.new B();//need of inclosing instance
A.C obj2 =new A.C();
// not need of reference of object of outer class….
}
}
मुझे नहीं लगता कि यहां जोड़ने के लिए बहुत कुछ है, अधिकांश उत्तर पूरी तरह से स्थैतिक नेस्टेड वर्ग और इनर वर्ग के बीच के अंतरों की व्याख्या करते हैं। हालाँकि, नेस्टेड क्लासेस बनाम इनर क्लासेस का उपयोग करते समय निम्नलिखित समस्या पर विचार करें। जवाब के एक जोड़े में उल्लेख के रूप में इनर क्लासों के बिना instantiated नहीं किया जा सकता है और उनके संलग्नित क्लास के उदाहरण है, जिसमें मतलब है कि वे पकड़ एक सूचक तथ्य जीसी की वजह से उनके संलग्नित क्लास के उदाहरण है, जिसमें स्मृति अतिप्रवाह या ढेर अतिप्रवाह अपवाद को जन्म दे सकता करने के लिए कचरा जमा करने में सक्षम नहीं होगा, भले ही वे किसी भी अधिक उपयोग नहीं किए जाते हैं। यह स्पष्ट करने के लिए निम्नलिखित कोड देखें:
public class Outer {
public class Inner {
}
public Inner inner(){
return new Inner();
}
@Override
protected void finalize() throws Throwable {
// as you know finalize is called by the garbage collector due to destroying an object instance
System.out.println("I am destroyed !");
}
}
public static void main(String arg[]) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
// out instance is no more used and should be garbage collected !!!
// However this will not happen as inner instance is still alive i.e used, not null !
// and outer will be kept in memory until inner is destroyed
outer = null;
//
// inner = null;
//kick out garbage collector
System.gc();
}
यदि आप टिप्पणी को हटाते हैं, तो // inner = null;
कार्यक्रम " मैं नष्ट हो गया हूँ " डाल देगा , लेकिन इस टिप्पणी को रखने से यह नहीं होगा।
कारण यह है कि सफेद आंतरिक उदाहरण अभी भी संदर्भित है जीसी इसे एकत्र नहीं कर सकता है और क्योंकि यह बाहरी संकेत भी एकत्र नहीं करता है (इसका एक संकेतक है)। आपके प्रोजेक्ट में इन ऑब्जेक्ट्स के पर्याप्त होने और मेमोरी से बाहर चला जा सकता है।
स्थिर आंतरिक वर्गों की तुलना में जो आंतरिक वर्ग उदाहरण के लिए एक बिंदु नहीं रखता है क्योंकि यह संबंधित नहीं बल्कि वर्ग से संबंधित है। यदि आप इनर क्लास को स्टैटिक बनाते हैं और उपर्युक्त करते हैं तो उपरोक्त प्रोग्राम " मैं नष्ट हो गया! " प्रिंट कर सकता हैOuter.Inner i = new Outer.Inner();
नेस्टेड क्लास एक बहुत ही सामान्य शब्द है: हर वर्ग जो शीर्ष स्तर का नहीं है वह एक नेस्टेड क्लास है। एक आंतरिक वर्ग एक गैर-स्थैतिक नेस्टेड वर्ग है। जोसेफ डार्सी ने नेस्टेड, इनर, मेंबर और टॉप-लेवल क्लासेस के बारे में बहुत अच्छी व्याख्या लिखी ।
उम्म ... एक आंतरिक वर्ग एक नेस्टेड वर्ग है ... क्या आपका मतलब अनाम वर्ग और आंतरिक वर्ग है?
संपादित करें: यदि आप वास्तव में आंतरिक बनाम अनाम का मतलब ... एक आंतरिक वर्ग सिर्फ एक वर्ग के भीतर परिभाषित एक वर्ग है जैसे:
public class A {
public class B {
}
}
जबकि एक अनाम वर्ग अनाम रूप से परिभाषित एक वर्ग का विस्तार है, इसलिए कोई वास्तविक "वर्ग परिभाषित नहीं है, जैसे कि:
public class A {
}
A anon = new A() { /* you could change behavior of A here */ };
आगे संपादित करें:
विकिपीडिया का दावा है कि जावा में अंतर है, लेकिन मैं 8 वर्षों से जावा के साथ काम कर रहा हूं, और यह पहली बार है जब मैंने इस तरह का अंतर सुना है ... इस बात का उल्लेख नहीं है कि दावा वापस करने के लिए कोई संदर्भ नहीं है ... नीचे लाइन, एक आंतरिक वर्ग एक वर्ग (स्थिर या नहीं) के भीतर परिभाषित एक वर्ग है, और नेस्टेड का मतलब एक ही शब्द है।
स्टैटिक और नॉन-स्टैटिक नेस्टेड क्लास के बीच एक सूक्ष्म अंतर होता है ... मूल रूप से नॉन-स्टैटिक इनर क्लास में एन्क्लोज़िंग क्लास के फ़ील्ड्स और तरीकों का निहितार्थ होता है (इस प्रकार उन्हें स्टैटिक संदर्भ में निर्मित नहीं किया जा सकता है, यह एक कंपाइलर होगा त्रुटि)। दूसरी ओर स्टैटिक नेस्टेड क्लासेस, उदाहरण के लिए खेतों और विधियों तक अंतर्निहित पहुंच नहीं रखते हैं, और एक स्थिर संदर्भ में इसका निर्माण किया जा सकता है।
लक्ष्यीकरण सीखने वाले, जो जावा और / या नेस्टेड कक्षाओं के लिए नौसिखिया हैं
नस्टेड क्लासेस या तो हो सकते हैं:
1. स्टेटिक नेस्टेड क्लासेस।
2. नॉन स्टेटिक नेस्टेड क्लासेस। ( इनर क्लासेस के रूप में भी जाना जाता है ) => कृपया इसे याद रखें
1. इनर वर्ग
उदाहरण:
class OuterClass {
/* some code here...*/
class InnerClass { }
/* some code here...*/
}
भीतरी वर्ग नेस्टेड वर्गों के सबसेट हैं:
इनर वर्ग की विशेषता:
2. स्थिर नेस्टेड वर्ग:
उदाहरण:
class EnclosingClass {
static class Nested {
void someMethod() { System.out.println("hello SO"); }
}
}
केस 1: गैर-एनक्लोजिंग क्लास से एक स्थिर नेस्टेड क्लास को इंस्टेंट करना
class NonEnclosingClass {
public static void main(String[] args) {
/*instantiate the Nested class that is a static
member of the EnclosingClass class:
*/
EnclosingClass.Nested n = new EnclosingClass.Nested();
n.someMethod(); //prints out "hello"
}
}
केस 2: एनक्लोजिंग क्लास से स्टैटिक नेस्टेड क्लास को इंस्टेंट करना
class EnclosingClass {
static class Nested {
void anotherMethod() { System.out.println("hi again"); }
}
public static void main(String[] args) {
//access enclosed class:
Nested n = new Nested();
n.anotherMethod(); //prints out "hi again"
}
}
स्थैतिक कक्षाओं की विशेषता:
निष्कर्ष:
प्रश्न: जावा में एक आंतरिक वर्ग और एक स्थिर नेस्टेड वर्ग के बीच मुख्य अंतर क्या है?
उत्तर: बस ऊपर उल्लिखित प्रत्येक वर्ग की बारीकियों के माध्यम से जाना।
आंतरिक वर्ग और नेस्टेड स्थिर वर्गजावा में दोनों एक और क्लास के अंदर घोषित की गई क्लास हैं, जिन्हें जावा में टॉप लेवल क्लास कहा जाता है। जावा शब्दावली में, यदि आप एक नेस्टेड क्लास स्टेटिक घोषित करते हैं, तो इसे जावा में नेस्टेड स्टेटिक क्लास कहा जाएगा, जबकि नॉन स्टैटिक नेस्टेड क्लास को केवल इनर क्लास कहा जाता है।
जावा में इनर क्लास क्या है?
कोई भी वर्ग जो एक शीर्ष स्तर नहीं है या किसी अन्य वर्ग के अंदर घोषित किया गया है उसे नेस्टेड क्लास के रूप में जाना जाता है और उन नेस्टेड कक्षाओं में से, जिस वर्ग को गैर स्थिर घोषित किया जाता है उसे जावा में इनर क्लास के रूप में जाना जाता है। जावा में तीन प्रकार के आंतरिक वर्ग हैं:
1) स्थानीय आंतरिक वर्ग - एक कोड ब्लॉक या विधि के अंदर घोषित किया जाता है।
2) बेनामी आंतरिक वर्ग - एक ऐसा वर्ग है जिसका संदर्भ देने के लिए नाम नहीं है और इसे उसी स्थान पर आरम्भ किया जाता है जहाँ इसे बनाया जाता है।
3) सदस्य आंतरिक वर्ग - बाहरी वर्ग के गैर स्थिर सदस्य के रूप में घोषित किया जाता है।
public class InnerClassTest {
public static void main(String args[]) {
//creating local inner class inside method i.e. main()
class Local {
public void name() {
System.out.println("Example of Local class in Java");
}
}
//creating instance of local inner class
Local local = new Local();
local.name(); //calling method from local inner class
//Creating anonymous inner class in Java for implementing thread
Thread anonymous = new Thread(){
@Override
public void run(){
System.out.println("Anonymous class example in java");
}
};
anonymous.start();
//example of creating instance of inner class
InnerClassTest test = new InnerClassTest();
InnerClassTest.Inner inner = test.new Inner();
inner.name(); //calling method of inner class
}
//Creating Inner class in Java
private class Inner{
public void name(){
System.out.println("Inner class example in java");
}
}
}
जावा में स्थिर वर्ग क्या है?
नेस्टेड स्टैटिक क्लास एक अन्य क्लास है जिसे क्लास के अंदर सदस्य के रूप में घोषित किया जाता है और स्टैटिक बनाया जाता है। नेस्टेड स्टैटिक क्लास को बाहरी वर्ग का सदस्य भी घोषित किया जाता है और इसे किसी अन्य सदस्य की तरह निजी, सार्वजनिक या संरक्षित किया जा सकता है। नेस्टेड स्टैटिक क्लास के मुख्य लाभ में से एक यह है कि नेस्टेड स्टैटिक क्लास का उदाहरण बाहरी वर्ग के किसी भी संलग्न उदाहरण से जुड़ा नहीं है। जावा में नेस्टेड स्टैटिक क्लास का उदाहरण बनाने के लिए आपको बाहरी वर्ग के किसी भी उदाहरण की आवश्यकता नहीं है ।
1) यह निजी सहित बाहरी वर्ग के स्थिर डेटा सदस्यों तक पहुँच सकता है ।
2) स्टेटिक नेस्टेड क्लास गैर-स्थैतिक (उदाहरण) डेटा सदस्य या विधि का उपयोग नहीं कर सकता है ।
public class NestedStaticExample {
public static void main(String args[]){
StaticNested nested = new StaticNested();
nested.name();
}
//static nested class in java
private static class StaticNested{
public void name(){
System.out.println("static nested class example in java");
}
}
}
Ref: उदाहरण के साथ जावा में इनर क्लास और नेस्टेड स्टेटिक क्लास
मुझे लगता है कि यहां के लोगों को पोस्टर पर ध्यान देना चाहिए कि: स्टेटिक नेस्ट क्लास सिर्फ पहली आंतरिक कक्षा है। उदाहरण के लिए:
public static class A {} //ERROR
public class A {
public class B {
public static class C {} //ERROR
}
}
public class A {
public static class B {} //COMPILE !!!
}
इसलिए, संक्षेप में बताएं, स्थिर वर्ग यह निर्भर नहीं करता है कि उसका कौन सा वर्ग है। इसलिए, वे सामान्य वर्ग में नहीं हो सकते। (क्योंकि सामान्य वर्ग को एक उदाहरण की आवश्यकता होती है)।
जब हम एक वर्ग के अंदर स्थिर सदस्य वर्ग की घोषणा करते हैं, तो इसे शीर्ष स्तर के नेस्टेड क्लास या एक स्थिर नेस्टेड क्लास के रूप में जाना जाता है। इसे नीचे प्रदर्शित किया जा सकता है:
class Test{
private static int x = 1;
static class A{
private static int y = 2;
public static int getZ(){
return B.z+x;
}
}
static class B{
private static int z = 3;
public static int getY(){
return A.y;
}
}
}
class TestDemo{
public static void main(String[] args){
Test t = new Test();
System.out.println(Test.A.getZ());
System.out.println(Test.B.getY());
}
}
जब हम एक वर्ग के अंदर गैर-स्थैतिक सदस्य वर्ग की घोषणा करते हैं तो इसे आंतरिक वर्ग के रूप में जाना जाता है। भीतरी वर्ग का प्रदर्शन नीचे दिया जा सकता है:
class Test{
private int i = 10;
class A{
private int i =20;
void display(){
int i = 30;
System.out.println(i);
System.out.println(this.i);
System.out.println(Test.this.i);
}
}
}
निम्नलिखित का एक उदाहरण है static nested class
और inner class
:
OuterClass.java
public class OuterClass {
private String someVariable = "Non Static";
private static String anotherStaticVariable = "Static";
OuterClass(){
}
//Nested classes are static
static class StaticNestedClass{
private static String privateStaticNestedClassVariable = "Private Static Nested Class Variable";
//can access private variables declared in the outer class
public static void getPrivateVariableofOuterClass(){
System.out.println(anotherStaticVariable);
}
}
//non static
class InnerClass{
//can access private variables of outer class
public String getPrivateNonStaticVariableOfOuterClass(){
return someVariable;
}
}
public static void accessStaticClass(){
//can access any variable declared inside the Static Nested Class
//even if it private
String var = OuterClass.StaticNestedClass.privateStaticNestedClassVariable;
System.out.println(var);
}
}
OuterClassTest:
public class OuterClassTest {
public static void main(String[] args) {
//access the Static Nested Class
OuterClass.StaticNestedClass.getPrivateVariableofOuterClass();
//test the private variable declared inside the static nested class
OuterClass.accessStaticClass();
/*
* Inner Class Test
* */
//Declaration
//first instantiate the outer class
OuterClass outerClass = new OuterClass();
//then instantiate the inner class
OuterClass.InnerClass innerClassExample = outerClass. new InnerClass();
//test the non static private variable
System.out.println(innerClassExample.getPrivateNonStaticVariableOfOuterClass());
}
}
मुझे लगता है कि उपर्युक्त उत्तरों में से कोई भी आपको एक नेस्टेड क्लास और एप्लिकेशन डिज़ाइन के कार्यकाल में एक स्थिर नेस्टेड वर्ग के बीच का वास्तविक उदाहरण नहीं देता है। और स्टेटिक नेस्टेड क्लास और इनर क्लास के बीच मुख्य अंतर बाहरी क्लास इंस्टेंस फील्ड को एक्सेस करने की क्षमता है।
आइए हम निम्नलिखित दो उदाहरणों पर एक नज़र डालें।
स्टेटिक नेस्ट क्लास: स्टैटिक नेस्टेड क्लास का उपयोग करने का एक अच्छा उदाहरण बिल्डर पैटर्न ( https://dzone.com/articles/design-patterns-the-builder-pattern ) है।
BankAccount के लिए हम मुख्य रूप से एक स्थिर नेस्टेड क्लास का उपयोग करते हैं
बाहरी वर्ग से पहले स्टेटिक नेस्ट क्लास का उदाहरण बनाया जा सकता है।
बिल्डर पैटर्न में, बिल्डर एक सहायक वर्ग है जिसका उपयोग बैंकअकाउंट बनाने के लिए किया जाता है।
public class BankAccount {
private long accountNumber;
private String owner;
...
public static class Builder {
private long accountNumber;
private String owner;
...
static public Builder(long accountNumber) {
this.accountNumber = accountNumber;
}
public Builder withOwner(String owner){
this.owner = owner;
return this;
}
...
public BankAccount build(){
BankAccount account = new BankAccount();
account.accountNumber = this.accountNumber;
account.owner = this.owner;
...
return account;
}
}
}
इनर क्लास: इनर क्लास का एक सामान्य उपयोग इवेंट हैंडलर को परिभाषित करना है। https://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html
MyClass के लिए, हम आंतरिक वर्ग का उपयोग करते हैं, मुख्यतः क्योंकि:
आंतरिक वर्ग MyAdapter को बाहरी वर्ग के सदस्य तक पहुँचने की आवश्यकता है।
उदाहरण में, MyAdapter केवल MyClass से संबद्ध है। कोई अन्य वर्ग MyAdapter से संबंधित नहीं हैं। इसलिए नाम सम्मेलन का उपयोग किए बिना उन्हें एक साथ व्यवस्थित करना बेहतर है
public class MyClass extends Applet {
...
someObject.addMouseListener(new MyAdapter());
...
class MyAdapter extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
...// Event listener implementation goes here...
...// change some outer class instance property depend on the event
}
}
}
सबसे पहले स्टैटिक क्लास नामक ऐसी कोई क्लास नहीं है। स्टैटिक मॉडिफायर इनर क्लास (जिसे नेस्टेड क्लास कहा जाता है) के साथ उपयोग करता है, कहता है कि यह आउटर क्लास का एक स्टैटिक मेंबर है, जिसका मतलब है कि हम इसे अन्य स्टैटिक सदस्यों की तरह एक्सेस कर सकते हैं और बिना किसी के पास बाहरी वर्ग का उदाहरण। (जो मूल रूप से स्थैतिक का लाभ है।)
नेस्टेड क्लास और रेगुलर इनर क्लास का उपयोग करने के बीच अंतर है:
OuterClass.InnerClass inner = new OuterClass().new InnerClass();
पहले हम आउटरक्लास को तुरंत कर सकते हैं फिर हम इनर तक पहुंच सकते हैं।
लेकिन अगर क्लास नेस्टेड है तो सिंटैक्स है:
OuterClass.InnerClass inner = new OuterClass.InnerClass();
जो स्थिर सिंटैक्स का उपयोग करता है, स्थिर कीवर्ड के सामान्य कार्यान्वयन के रूप में।
जावा प्रोग्रामिंग भाषा आपको एक वर्ग को दूसरी कक्षा में परिभाषित करने की अनुमति देती है। इस तरह के एक वर्ग को एक नेस्टेड वर्ग कहा जाता है और यहाँ चित्रित किया गया है:
class OuterClass {
...
class NestedClass {
...
}
}
नेस्टेड वर्गों को दो श्रेणियों में विभाजित किया जाता है: स्थिर और गैर-स्थिर। जिन वर्गों को स्थिर घोषित किया जाता है, उन्हें स्टेटिक नेस्टेड क्लास कहा जाता है। नॉन-स्टैटिक नेस्टेड क्लासेस को इनर क्लास कहा जाता है। एक बात जो हमें ध्यान में रखनी चाहिए वह है नॉन-स्टैटिक नेस्टेड क्लासेस (इनर क्लासेज), जो कि एनक्लोजिंग क्लास के अन्य सदस्यों तक पहुँच रखती हैं, भले ही वे निजी घोषित हों। स्टेटिक नेस्टेड क्लासेस के पास केवल एनक्लोजिंग क्लास के अन्य सदस्यों तक पहुंच होती है यदि वे स्थिर हैं। यह बाहरी वर्ग के गैर स्थिर सदस्यों तक नहीं पहुंच सकता है। क्लास के तरीकों और चर के साथ, एक स्थिर नेस्टेड क्लास अपने बाहरी वर्ग के साथ जुड़ा हुआ है। उदाहरण के लिए, स्थिर नेस्टेड क्लास के लिए ऑब्जेक्ट बनाने के लिए, इस सिंटैक्स का उपयोग करें:
OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();
एक आंतरिक कक्षा को तुरंत करने के लिए, आपको सबसे पहले बाहरी कक्षा को तुरंत बदलना होगा। फिर, इस सिंटैक्स के साथ बाहरी ऑब्जेक्ट के भीतर आंतरिक ऑब्जेक्ट बनाएं:
OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();
क्यों हम नेस्टेड कक्षाओं का उपयोग करते हैं
अंतर यह है कि एक नेस्टेड क्लास डिक्लेरेशन जो कि स्टैटिक भी है, को एन्क्लेविंग क्लास के बाहर तत्काल किया जा सकता है।
जब आपके पास एक नेस्टेड क्लास घोषणा होती है जो स्थिर नहीं होती है , जिसे आंतरिक वर्ग के रूप में भी जाना जाता है , तो जावा आपको एनक्लोजिंग क्लास के अलावा इसे तुरंत नहीं होने देगा। आंतरिक वर्ग से निर्मित वस्तु बाहरी वर्ग से निर्मित वस्तु से जुड़ी होती है, इसलिए आंतरिक वर्ग बाहरी क्षेत्रों को संदर्भित कर सकता है।
लेकिन अगर यह स्थिर है, तो लिंक मौजूद नहीं है, बाहरी क्षेत्रों तक पहुँचा नहीं जा सकता है (किसी अन्य ऑब्जेक्ट की तरह एक साधारण संदर्भ को छोड़कर) और इसलिए आप स्वयं द्वारा नेस्टेड क्लास को तुरंत कर सकते हैं।
मैंने विभिन्न संभावित सही और त्रुटि परिदृश्य का वर्णन किया है जो जावा कोड में हो सकता है।
class Outter1 {
String OutStr;
Outter1(String str) {
OutStr = str;
}
public void NonStaticMethod(String st) {
String temp1 = "ashish";
final String tempFinal1 = "ashish";
// below static attribute not permitted
// static String tempStatic1 = "static";
// below static with final attribute not permitted
// static final String tempStatic1 = "ashish";
// synchronized keyword is not permitted below
class localInnerNonStatic1 {
synchronized public void innerMethod(String str11) {
str11 = temp1 +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// static method with final not permitted
public static void innerStaticMethod(String str11) {
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
}
// static class not permitted below
// static class localInnerStatic1 { }
}
public static void StaticMethod(String st) {
String temp1 = "ashish";
final String tempFinal1 = "ashish";
// static attribute not permitted below
//static String tempStatic1 = "static";
// static with final attribute not permitted below
// static final String tempStatic1 = "ashish";
class localInnerNonStatic1 {
public void innerMethod(String str11) {
str11 = temp1 +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// static method with final not permitted
public static void innerStaticMethod(String str11) {
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
}
// static class not permitted below
// static class localInnerStatic1 { }
}
// synchronized keyword is not permitted
static class inner1 {
static String temp1 = "ashish";
String tempNonStatic = "ashish";
// class localInner1 {
public void innerMethod(String str11) {
str11 = temp1 +" sharma";
str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
public static void innerStaticMethod(String str11) {
// error in below step
str11 = temp1 +" india";
//str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
//}
}
//synchronized keyword is not permitted below
class innerNonStatic1 {
//This is important we have to keep final with static modifier in non
// static innerclass below
static final String temp1 = "ashish";
String tempNonStatic = "ashish";
// class localInner1 {
synchronized public void innerMethod(String str11) {
tempNonStatic = tempNonStatic +" ...";
str11 = temp1 +" sharma";
str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// error in below step
public static void innerStaticMethod(String str11) {
// error in below step
// str11 = tempNonStatic +" india";
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
//}
}
}
item 22 : Favor static member classes over non static