class OuterClass {
...
static class StaticNestedClass {
...
}
class InnerClass {
...
}
}
इन आंतरिक वर्गों को नेस्टेड कहा जाता है। वे 2 प्रकारों में विभाजित हैं:
- गैर स्थैतिक नेस्टेड कक्षाएं। इन्हें आंतरिक वर्ग भी कहा जाता है।
- स्टेटिक नेस्टेड क्लासेस।
- एक स्थानीय वर्ग
- एक अनाम वर्ग

public class Bicycle {
private String model;
private int weight;
public Bicycle(String model, int weight) {
this.model = model;
this.weight = weight;
}
public void start() {
System.out.println("Let's go!");
}
public class Handlebar {
public void right() {
System.out.println("Steer right!");
}
public void left() {
System.out.println("Steer left!");
}
}
public class Seat {
public void up() {
System.out.println("Seat up!");
}
public void down() {
System.out.println("Seat down!");
}
}
}
यहाँ हमारे पास Bicycle
कक्षा है। इसके 2 क्षेत्र और 1 विधि है: start()
. 
Handlebar
और Seat
। उनका कोड Bicycle
क्लास के अंदर लिखा होता है। ये पूर्ण वर्ग हैं: जैसा कि आप देख सकते हैं, उनमें से प्रत्येक की अपनी विधियाँ हैं। इस बिंदु पर, आपके पास एक प्रश्न हो सकता है: दुनिया में हम एक वर्ग को दूसरे के अंदर क्यों रखेंगे? उन्हें आंतरिक वर्ग क्यों बनाते हैं? ठीक है, मान लीजिए कि हमें अपने कार्यक्रम में हैंडलबार और सीट की अवधारणाओं के लिए अलग-अलग कक्षाओं की आवश्यकता है। बेशक, हमारे लिए उन्हें घोंसला बनाना जरूरी नहीं है! हम सामान्य वर्ग बना सकते हैं। उदाहरण के लिए, इस तरह:
public class Handlebar {
public void right() {
System.out.println("Steer right!");
}
public void left() {
System.out.println("Steer left");
}
}
public class Seat {
public void up() {
System.out.println("Seat up!");
}
public void down() {
System.out.println("Seat down!");
}
}
बहुत अच्छा प्रश्न ! बेशक, हम प्रौद्योगिकी द्वारा सीमित नहीं हैं। ऐसा करना निश्चित रूप से एक विकल्प है। यहां, एक विशिष्ट कार्यक्रम और उसके उद्देश्य के परिप्रेक्ष्य से कक्षाओं का सही डिजाइन अधिक महत्वपूर्ण है। आंतरिक वर्ग एक इकाई को अलग करने के लिए हैं जो किसी अन्य इकाई से अटूट रूप से जुड़ा हुआ है। हैंडलबार, सीट और पैडल एक साइकिल के घटक हैं। साइकिल से अलग होने से उन्हें ज्यादा मतलब नहीं है। यदि हम इन सभी अवधारणाओं को अलग-अलग सार्वजनिक वर्ग बनाते हैं, तो हमारे कार्यक्रम में इस तरह का कोड होता:
public class Main {
public static void main(String[] args) {
Handlebar handlebar = new Handlebar();
handlebar.right();
}
}
हम्म... इस कोड का अर्थ समझाना और भी मुश्किल है। हमारे पास कुछ अस्पष्ट हैंडलबार हैं (यह क्यों आवश्यक है? ईमानदार होने के लिए कोई विचार नहीं है)। और यह हत्था दाहिनी ओर मुड़ जाता है... बिल्कुल अपने आप, बिना साइकिल के... किसी कारणवश। हैंडलबार की अवधारणा को साइकिल की अवधारणा से अलग करके, हमने अपने कार्यक्रम में कुछ तर्क खो दिए। एक आंतरिक वर्ग का उपयोग करते हुए, कोड बहुत अलग दिखता है:
public class Main {
public static void main(String[] args) {
Bicycle peugeot = new Bicycle("Peugeot", 120);
Bicycle.Handlebar handlebar = peugeot.new Handlebar();
Bicycle.Seat seat = peugeot.new Seat();
seat.up();
peugeot.start();
handlebar.left();
handlebar.right();
}
}
कंसोल आउटपुट:
Seat up!
Let's go!
Steer left!
Steer right!
अब हम जो देखते हैं वह अचानक समझ में आता है! :) हमने एक साइकिल वस्तु बनाई। हमने दो साइकिल "सबऑब्जेक्ट्स" बनाए - एक हैंडलबार और एक सीट। हमने आराम के लिए सीट उठाई और चले गए: आवश्यकतानुसार पेडलिंग और स्टीयरिंग! :) हमें जिन तरीकों की आवश्यकता है उन्हें उपयुक्त वस्तुओं पर बुलाया जाता है। यह सब आसान और सुविधाजनक है। इस उदाहरण में, हैंडलबार और सीट को अलग करना इनकैप्सुलेशन को बढ़ाता है (हम संबंधित वर्ग के अंदर साइकिल के पुर्जों के बारे में डेटा छिपाते हैं) और हमें अधिक विस्तृत सार बनाने की सुविधा देते हैं। अब आइए एक अलग स्थिति देखें। मान लीजिए हम एक ऐसा प्रोग्राम बनाना चाहते हैं जो बाइक की दुकान और बाइक के लिए स्पेयर पार्ट्स का अनुकरण करता है। 
-
एक आंतरिक वर्ग की वस्तु बाहरी वर्ग की वस्तु के बिना मौजूद नहीं हो सकती।
Seat
यह समझ में आता है: यही कारण है कि हमने अपने कार्यक्रम में और आंतरिक कक्षाएं बनाईंHandlebar
- ताकि हम अनाथ हैंडलबार्स और सीटों के साथ समाप्त न हों।यह कोड संकलित नहीं होता है:
public static void main(String[] args) { Handlebar handlebar = new Handlebar(); }
इससे एक और महत्वपूर्ण विशेषता सामने आती है:
-
आंतरिक वर्ग की एक वस्तु की बाहरी वर्ग के चरों तक पहुँच होती है।
उदाहरण के लिए, आइए अपनी कक्षा
int seatPostDiameter
में एक चर (सीटपोस्ट के व्यास का प्रतिनिधित्व) जोड़ें।Bicycle
फिर
Seat
आंतरिक कक्षा में, हम एक विधि बना सकते हैंdisplaySeatProperties()
जो सीट के गुणों को प्रदर्शित करती है:public class Bicycle { private String model; private int weight; private int seatPostDiameter; public Bicycle(String model, int weight, int seatPostDiameter) { this.model = model; this.weight = weight; this.seatPostDiameter = seatPostDiameter; } public void start() { System.out.println("Let's go!"); } public class Seat { public void up() { System.out.println("Seat up!"); } public void down() { System.out.println("Seat down!"); } public void displaySeatProperties() { System.out.println("Seat properties: seatpost diameter = " + Bicycle.this.seatPostDiameter); } } }
और अब हम इस जानकारी को अपने प्रोग्राम में प्रदर्शित कर सकते हैं:
public class Main { public static void main(String[] args) { Bicycle bicycle = new Bicycle("Peugeot", 120, 40); Bicycle.Seat seat = bicycle.new Seat(); seat.displaySeatProperties(); } }
कंसोल आउटपुट:
Seat properties: seatpost diameter = 40
टिप्पणी:नया वेरिएबल सबसे सख्त एक्सेस मॉडिफायर (
private
) के साथ घोषित किया गया है। और अभी भी आंतरिक वर्ग की पहुंच है! -
बाहरी वर्ग की स्थिर विधि में आंतरिक वर्ग की वस्तु नहीं बनाई जा सकती है।
यह विशिष्ट विशेषताओं द्वारा समझाया गया है कि आंतरिक कक्षाएं कैसे व्यवस्थित की जाती हैं। एक आंतरिक वर्ग में पैरामीटर के साथ कन्स्ट्रक्टर हो सकते हैं, या केवल डिफ़ॉल्ट कन्स्ट्रक्टर हो सकते हैं। लेकिन इसकी परवाह किए बिना, जब हम एक आंतरिक वर्ग की वस्तु बनाते हैं, तो बाहरी वर्ग की वस्तु का संदर्भ अदृश्य रूप से आंतरिक वर्ग की बनाई गई वस्तु को दिया जाता है। आखिरकार, ऐसे ऑब्जेक्ट संदर्भ की उपस्थिति एक परम आवश्यकता है। अन्यथा, हम इनर क्लास के ऑब्जेक्ट नहीं बना पाएंगे।
लेकिन अगर बाहरी वर्ग की कोई विधि स्थिर है, तो हमारे पास बाहरी वर्ग की कोई वस्तु नहीं हो सकती है! और यह तर्क का उल्लंघन होगा कि एक आंतरिक वर्ग कैसे काम करता है। इस स्थिति में, कंपाइलर एक त्रुटि उत्पन्न करेगा:
public static Seat createSeat() { // Bicycle.this cannot be referenced from a static context return new Seat(); }
-
एक आंतरिक वर्ग में स्थिर चर और विधियाँ नहीं हो सकती हैं।
तर्क समान है: स्थैतिक तरीके और चर मौजूद हो सकते हैं और किसी वस्तु की अनुपस्थिति में भी उन्हें बुलाया या संदर्भित किया जा सकता है।
लेकिन बाहरी वर्ग के किसी वस्तु के बिना, हमारे पास आंतरिक वर्ग तक पहुँच नहीं होगी।
एक स्पष्ट विरोधाभास! यही कारण है कि आंतरिक कक्षाओं में स्थैतिक चर और विधियों की अनुमति नहीं है।
यदि आप उन्हें बनाने का प्रयास करते हैं तो संकलक एक त्रुटि उत्पन्न करेगा:
public class Bicycle { private int weight; public class Seat { // An inner class cannot have static declarations public static void displaySeatProperties() { System.out.println("Seat properties: seatpost diameter = " + Bicycle.this.seatPostDiameter); } } }
-
आंतरिक वर्ग का ऑब्जेक्ट बनाते समय, इसका एक्सेस संशोधक महत्वपूर्ण होता है।
एक आंतरिक वर्ग को मानक पहुँच संशोधक के साथ चिह्नित किया जा सकता है:
public
,private
,protected
, औरpackage private
।यह क्यों मायने रखता है?
यह प्रभावित करता है कि हम अपने प्रोग्राम में इनर क्लास के उदाहरण कहाँ बना सकते हैं।
यदि हमारी
Seat
कक्षा के रूप में घोषित किया जाता हैpublic
, तो हमSeat
किसी अन्य वर्ग में वस्तुएँ बना सकते हैं। केवल आवश्यकता यह है कि बाहरी वर्ग की वस्तु भी मौजूद होनी चाहिए।वैसे, हम यहां पहले ही ऐसा कर चुके हैं:
public class Main { public static void main(String[] args) { Bicycle peugeot = new Bicycle("Peugeot", 120); Bicycle.Handlebar handlebar = peugeot.new Handlebar(); Bicycle.Seat seat = peugeot.new Seat(); seat.up(); peugeot.start(); handlebar.left(); handlebar.right(); } }
हम आसानी से कक्षा
Handlebar
से आंतरिक कक्षा तक पहुँच प्राप्त कर लेते हैं।Main
यदि हम इनर क्लास को घोषित करते हैं
private
, तो हम केवल बाहरी क्लास के अंदर ही ऑब्जेक्ट बना पाएंगे।Seat
हम अब "बाहरी" वस्तु नहीं बना सकते हैं :private class Seat { // Methods } public class Main { public static void main(String[] args) { Bicycle bicycle = new Bicycle("Peugeot", 120, 40); // Bicycle.Seat has private access in Bicycle Bicycle.Seat seat = bicycle.new Seat(); } }
आप शायद तर्क को पहले ही समझ चुके हैं :)
-
आंतरिक कक्षाओं के लिए एक्सेस संशोधक सामान्य चर के समान ही काम करते हैं।
संशोधक
protected
एक ही पैकेज में उप-वर्गों और कक्षाओं में एक आवृत्ति चर तक पहुंच प्रदान करता है।protected
आंतरिक कक्षाओं के लिए भी काम करता है। हमprotected
आंतरिक वर्ग की वस्तुएँ बना सकते हैं:- बाहरी वर्ग में;
- इसके उपवर्गों में;
- उन कक्षाओं में जो एक ही पैकेज में हैं।
यदि आंतरिक वर्ग में एक्सेस संशोधक (
package private
) नहीं है, तो आंतरिक वर्ग के ऑब्जेक्ट बनाए जा सकते हैं:- बाहरी वर्ग में;
- उन कक्षाओं में जो एक ही पैकेज में हैं।
आप संशोधक से लंबे समय से परिचित हैं, इसलिए यहां कोई समस्या नहीं है।
GO TO FULL VERSION