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