CodeGym /جاوا بلاگ /Random-UR /نیسٹڈ اندرونی کلاسز
John Squirrels
سطح
San Francisco

نیسٹڈ اندرونی کلاسز

گروپ میں شائع ہوا۔
ہائے! آج ہم ایک اہم موضوع پر بات کریں گے - جاوا میں نیسٹڈ کلاسز کیسے کام کرتی ہیں۔ جاوا آپ کو دوسری کلاس کے اندر کلاسز بنانے دیتا ہے۔
class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
    class InnerClass {
        ...
    }
}
ان اندرونی کلاسوں کو نیسٹڈ کہا جاتا ہے۔ وہ 2 اقسام میں تقسیم ہیں:
  1. غیر جامد نیسٹڈ کلاسز۔ ان کو اندرونی کلاسز بھی کہا جاتا ہے۔
  2. جامد نیسٹڈ کلاسز۔
بدلے میں، اندرونی کلاسوں کے دو الگ الگ ذیلی زمرے ہوتے ہیں۔ اندرونی طبقے کے علاوہ صرف اندرونی طبقے ہونے کے علاوہ، یہ بھی ہو سکتا ہے:
  • ایک مقامی کلاس
  • ایک گمنام کلاس
الجھن میں؟ :) یہ ٹھیک ہے. یہاں وضاحت کے لیے ایک خاکہ ہے۔ سبق کے دوران اس پر واپس آئیں اگر آپ اچانک اپنے آپ کو الجھن میں محسوس کریں! نیسٹڈ اندرونی کلاسز - 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(). نیسٹڈ اندرونی کلاسز - 3یہ ایک عام طبقے سے مختلف ہے کہ اس میں دو طبقات ہیں: 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!
اب جو ہم اچانک دیکھتے ہیں وہ معنی رکھتا ہے! :) ہم نے ایک سائیکل آبجیکٹ بنایا۔ ہم نے دو سائیکل "سببجیکٹس" بنائے — ایک ہینڈل بار اور ایک سیٹ۔ ہم نے آرام کے لیے سیٹ اٹھائی اور ہم چلے گئے: ضرورت کے مطابق پیڈلنگ اور اسٹیئرنگ! :) ہمیں درکار طریقوں کو مناسب اشیاء پر کہا جاتا ہے۔ یہ سب آسان اور آسان ہے۔ اس مثال میں، ہینڈل بار اور سیٹ کو الگ کرنے سے انکیپسولیشن میں اضافہ ہوتا ہے (ہم متعلقہ کلاس کے اندر سائیکل کے پرزوں کے بارے میں ڈیٹا چھپاتے ہیں) اور ہمیں مزید تفصیلی تجرید تخلیق کرنے دیتا ہے۔ اب ایک مختلف صورت حال کو دیکھتے ہیں۔ فرض کریں کہ ہم ایک ایسا پروگرام بنانا چاہتے ہیں جو موٹر سائیکل کی دکان اور بائک کے اسپیئر پارٹس کی تقلید کرے۔ نیسٹڈ اندرونی کلاسز - 4اس صورت حال میں، ہمارا سابقہ ​​حل کام نہیں کرے گا۔ موٹر سائیکل کی دکان پر، سائیکل کا ہر ایک حصہ سائیکل سے الگ ہونے پر بھی معنی رکھتا ہے۔ مثال کے طور پر، ہمیں "کسٹمر کو پیڈل بیچنا"، "نئی سیٹ خریدنا" وغیرہ جیسے طریقوں کی ضرورت ہوگی۔ یہاں اندرونی کلاسز کا استعمال کرنا غلطی ہو گی — ہمارے نئے پروگرام میں ہر انفرادی سائیکل کے حصے کا مطلب ہے کہ اس کا اپنا: اسے سائیکل کے تصور سے الگ کیا جا سکتا ہے۔ یہ بالکل وہی ہے جس پر آپ کو توجہ دینے کی ضرورت ہے اگر آپ سوچ رہے ہیں کہ آیا آپ کو اندرونی کلاسز استعمال کرنی چاہئیں یا تمام اداروں کو الگ الگ کلاسز کے طور پر منظم کرنا چاہیے۔ آبجیکٹ پر مبنی پروگرامنگ اس لحاظ سے اچھی ہے کہ یہ حقیقی دنیا کے اداروں کو ماڈل بنانا آسان بناتی ہے۔ اندرونی کلاسز استعمال کرنے کا فیصلہ کرتے وقت یہ آپ کا رہنما اصول ہو سکتا ہے۔ ایک حقیقی اسٹور میں، اسپیئر پارٹس سائیکلوں سے الگ ہوتے ہیں — یہ ٹھیک ہے۔ اس کا مطلب یہ ہے کہ پروگرام ڈیزائن کرتے وقت یہ بھی ٹھیک ہے۔ ٹھیک ہے، ہم نے "فلسفہ" کا پتہ لگا لیا ہے :) اب آئیے اندرونی طبقات کی اہم "تکنیکی" خصوصیات سے واقف ہوں۔ یہاں آپ کو یقینی طور پر یاد رکھنے اور سمجھنے کی ضرورت ہے:
  1. اندرونی طبقے کی کوئی چیز بیرونی طبقے کی چیز کے بغیر نہیں رہ سکتی۔

    Seatیہ سمجھ میں آتا ہے: یہی وجہ ہے کہ ہم نے اپنے پروگرام میں اور اندرونی کلاسیں بنائیں Handlebar- تاکہ ہم یتیم ہینڈل بار اور نشستوں کے ساتھ ختم نہ ہوں۔

    یہ کوڈ مرتب نہیں کرتا ہے:

    public static void main(String[] args) {
    
       Handlebar handlebar = new Handlebar();
    }

    اس سے ایک اور اہم خصوصیت مندرجہ ذیل ہے:

  2. اندرونی طبقے کی کسی چیز کو بیرونی طبقے کے متغیرات تک رسائی حاصل ہوتی ہے۔

    مثال کے طور پر، آئیے اپنی کلاس 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) کے ساتھ کیا گیا ہے۔ اور پھر بھی اندرونی طبقے تک رسائی ہے!

  3. اندرونی طبقے کی کوئی چیز بیرونی طبقے کے جامد طریقہ سے نہیں بنائی جا سکتی۔

    اس کی وضاحت ان مخصوص خصوصیات سے ہوتی ہے کہ اندرونی کلاسز کو کس طرح منظم کیا جاتا ہے۔ ایک اندرونی کلاس میں پیرامیٹرز کے ساتھ کنسٹرکٹر یا صرف ڈیفالٹ کنسٹرکٹر ہو سکتا ہے۔ لیکن اس سے قطع نظر، جب ہم اندرونی طبقے کی کوئی چیز بناتے ہیں، تو بیرونی طبقے کی چیز کا حوالہ پوشیدہ طور پر اندرونی طبقے کی تخلیق کردہ آبجیکٹ تک پہنچا دیا جاتا ہے۔ سب کے بعد، اس طرح کے ایک اعتراض کے حوالہ کی موجودگی ایک مطلق ضرورت ہے. بصورت دیگر، ہم اندرونی طبقے کی اشیاء نہیں بنا پائیں گے۔

    لیکن اگر بیرونی طبقے کا کوئی طریقہ جامد ہے، تو شاید ہمارے پاس بیرونی طبقے کی کوئی چیز نہ ہو! اور یہ اس منطق کی خلاف ورزی ہوگی کہ ایک اندرونی طبقہ کیسے کام کرتا ہے۔ اس صورت حال میں، مرتب کرنے والا ایک غلطی پیدا کرے گا:

    public static Seat createSeat() {
    
       // Bicycle.this cannot be referenced from a static context
       return new Seat();
    }
  4. ایک اندرونی طبقے میں جامد متغیرات اور طریقے نہیں ہو سکتے۔

    منطق ایک ہی ہے: جامد طریقے اور متغیرات موجود ہو سکتے ہیں اور کسی چیز کی غیر موجودگی میں بھی کہا جا سکتا ہے یا حوالہ دیا جا سکتا ہے۔

    لیکن بیرونی طبقے کے کسی شے کے بغیر، ہمیں اندرونی طبقے تک رسائی حاصل نہیں ہوگی۔

    ایک واضح تضاد! یہی وجہ ہے کہ اندرونی کلاسوں میں جامد متغیرات اور طریقوں کی اجازت نہیں ہے۔

    اگر آپ انہیں بنانے کی کوشش کرتے ہیں تو مرتب کرنے والا ایک خرابی پیدا کرے گا:

    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);
           }
       }
    }
  5. اندرونی طبقے کی کوئی چیز بناتے وقت، اس تک رسائی میں ترمیم کرنے والا اہم ہوتا ہے۔

    ایک اندرونی کلاس کو معیاری رسائی میں ترمیم کرنے والوں کے ساتھ نشان زد کیا جا سکتا ہے: 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();
       }
    }

    آپ شاید پہلے ہی منطق کو سمجھ چکے ہوں :)

  6. اندرونی کلاسوں کے لیے رسائی میں ترمیم کرنے والے وہی کام کرتے ہیں جیسے عام متغیرات کے لیے۔

    ترمیم protectedکنندہ ذیلی طبقات اور کلاسوں میں ایک مثال کے متغیر تک رسائی فراہم کرتا ہے جو ایک ہی پیکیج میں ہیں۔

    protectedاندرونی کلاسوں کے لیے بھی کام کرتا ہے۔ ہم protectedاندرونی کلاس کی اشیاء بنا سکتے ہیں:

    • بیرونی کلاس میں؛
    • اس کے ذیلی طبقات میں؛
    • ان کلاسوں میں جو ایک ہی پیکیج میں ہیں۔

    اگر اندرونی طبقے میں رسائی موڈیفائر ( ) نہیں ہے تو package privateاندرونی کلاس کی اشیاء بنائی جا سکتی ہیں:

    • بیرونی کلاس میں؛
    • ان کلاسوں میں جو ایک ہی پیکیج میں ہیں۔

    آپ ایک طویل عرصے سے ترمیم کرنے والوں سے واقف ہیں، لہذا یہاں کوئی مسئلہ نہیں ہے۔

ابھی کے لیے بس اتنا ہی ہے :) لیکن سستی نہ کریں! اندرونی کلاسز ایک کافی وسیع موضوع ہے جسے ہم اگلے سبق میں دریافت کرنا جاری رکھیں گے۔ اب آپ اندرونی کلاسوں پر ہمارے کورس کے سبق کی اپنی یاد تازہ کر سکتے ہیں ۔ اور اگلی بار، آئیے سٹیٹک نیسٹڈ کلاسز کے بارے میں بات کرتے ہیں۔
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION