JavaRush /جاوا بلاگ /Random-UR /طریقے، ان کے پیرامیٹرز، تعامل اور اوورلوڈنگ

طریقے، ان کے پیرامیٹرز، تعامل اور اوورلوڈنگ

گروپ میں شائع ہوا۔
ہیلو دوبارہ! آخری لیکچر میں، ہم نے کلاسز اور کنسٹرکٹرز سے واقفیت حاصل کی، اور یہ سیکھا کہ خود کو کیسے بنانا ہے۔ طریقے، ان کے پیرامیٹرز، تعامل اور اوورلوڈنگ - 1آج ہم طریقوں کے طور پر کلاسوں کے اس طرح کے ایک لازمی حصہ پر قریبی نظر ڈالیں گے. ایک طریقہ کمانڈز کا ایک سیٹ ہے جو آپ کو پروگرام میں کچھ آپریشن کرنے کی اجازت دیتا ہے۔ دوسرے الفاظ میں، ایک طریقہ ایک فنکشن ہے؛ کچھ آپ کی کلاس کر سکتی ہے۔ پروگرامنگ کی دوسری زبانوں میں، طریقوں کو اکثر "فنکشنز" کہا جاتا ہے، لیکن جاوا میں لفظ "طریقہ" زیادہ مقبول ہو گیا ہے :) آخری لیکچر میں، اگر آپ کو یاد ہو، ہم نے کیٹ کلاس کے لیے آسان طریقے بنائے تھے تاکہ ہماری بلیاں میاؤں کر سکیں۔ اور چھلانگ:
public class Cat {

    String name;
    int age;

    public void sayMeow() {
        System.out.println("Meow!");
    }

    public void jump() {
        System.out.println("Jumping gallop!");
    }

    public static void main(String[] args) {
        Cat barsik = new Cat();
        barsik.age = 3;
        barsik.name = "Barsik";

        barsik.sayMeow();
        barsik.jump();
    }
}
sayMeow()اور jump()ہماری کلاس کے طریقے ہیں۔ ان کے کام کا نتیجہ کنسول کی پیداوار ہے:
Мяу!
Прыг-скок!
ہمارے طریقے کافی آسان ہیں: وہ صرف کنسول پر ٹیکسٹ پرنٹ کرتے ہیں۔ لیکن جاوا میں، طریقوں کا ایک اہم کام ہوتا ہے - انہیں کسی چیز کے ڈیٹا پر عمل کرنا چاہیے ۔ کسی چیز کے ڈیٹا کی قدر کو تبدیل کریں، اسے تبدیل کریں، اسے کنسول میں آؤٹ پٹ کریں، یا اس کے ساتھ کچھ اور کریں۔ ہمارے موجودہ طریقے آبجیکٹ کے ڈیٹا کے ساتھ کچھ نہیں کرتے ہیں Cat۔ آئیے ایک اور واضح مثال دیکھیں:
public class Truck {

    int length;
    int width;
    int height;
    int weight;

    public int getVolume() {
        int volume = length * width * height;
        return volume;
    }
}
مثال کے طور پر، ہمارے پاس ایک کلاس ہے جو ٹرک کی نمائندگی کرتی ہے Truck۔ ایک ٹرک ٹریلر کی لمبائی، چوڑائی اور اونچائی اور وزن ہوتا ہے (اس کی بعد میں ضرورت ہوگی)۔ طریقہ کار میں، getVolume()ہم حساب کرتے ہیں - ہم اپنے آبجیکٹ کے ڈیٹا کو ایک ایسی تعداد میں تبدیل کرتے ہیں جو حجم کی نشاندہی کرتا ہے (ہم لمبائی، چوڑائی اور اونچائی کو ضرب دیتے ہیں)۔ یہ وہ نمبر ہے جو طریقہ کار کا نتیجہ ہوگا۔ براہ کرم نوٹ کریں - طریقہ کی تفصیل میں یہ لکھا ہے public int getVolume۔ اس کا مطلب ہے کہ اس طریقہ کار کا نتیجہ فارم میں ایک عدد ہونا چاہیےint ۔ ہم نے طریقہ کار کے نتیجے کا حساب لگایا ہے، اور اب ہمیں اسے اپنے پروگرام میں واپس کرنا ہوگا جس نے طریقہ کہا ہے۔ جاوا میں کسی طریقہ کا نتیجہ واپس کرنے کے لیے کلیدی لفظ استعمال کیا جاتا ہے return۔
return volume;

طریقہ کار کے پیرامیٹرز

طریقے اقدار کو بطور ان پٹ قبول کر سکتے ہیں، جنہیں "طریقہ پیرامیٹرز" کہا جاتا ہے۔ getVolume()کلاس میں ہمارا موجودہ طریقہ Truckکسی بھی پیرامیٹرز کو قبول نہیں کرتا ہے، لہذا آئیے ٹرکوں کے ساتھ مثال کو بڑھانے کی کوشش کریں۔ آئیے ایک نئی کلاس بنائیں - BridgeOfficer. ایک پولیس افسر پل پر ڈیوٹی پر ہے اور گزرنے والے تمام ٹرکوں کی جانچ پڑتال کرتا ہے تاکہ یہ یقینی بنایا جا سکے کہ ان کا بوجھ جائز وزن کی حد سے زیادہ نہیں ہے۔
public class BridgeOfficer {

    int maxWeight;

    public BridgeOfficer(int normalWeight) {
        this.maxWeight = normalWeight;
    }

    public boolean checkTruck(Truck truck) {
        if (truck.weight > maxWeight) {
            return false;
        } else {
            return true;
        }
    }
}
طریقہ checkTruckان پٹ کے طور پر ایک پیرامیٹر لیتا ہے - ایک ٹرک آبجیکٹ Truck، اور یہ طے کرتا ہے کہ آیا افسر ٹرک کو پل پر جانے کی اجازت دے گا یا نہیں۔ طریقہ کار کے اندر کی منطق کافی آسان ہے: اگر ٹرک کا وزن زیادہ سے زیادہ قابل اجازت حد سے زیادہ ہو تو طریقہ واپس آجاتا ہے false۔ آپ کو دوسری سڑک تلاش کرنی پڑے گی :( اگر وزن زیادہ سے زیادہ سے کم یا اس کے برابر ہے، تو آپ گزر سکتے ہیں، اور طریقہ واپس آجاتا ہے true۔ آئیے پروگرامنگ سے وقفہ لیں اور حقیقی دنیا کی زندگی سے ایک سادہ سی مثال استعمال کرتے ہوئے اسے دیکھیں :) مان لیں کہ آپ بیمار ہو گئے اور کئی دنوں سے کام پر نہیں تھے۔ آپ اپنی بیماری کی چھٹی کے ساتھ اکاؤنٹنگ ڈیپارٹمنٹ میں آتے ہیں، جس کی ادائیگی آپ کو کرنی ہوگی۔ اگر ہم طریقوں سے مشابہت پیدا کرتے ہیں، تو اکاؤنٹنٹ کے پاس ایک طریقہ ہوتا ہے paySickLeave()("بیماری کی چھٹی ادا کریں")۔ آپ اس طریقہ کو پیرامیٹر کے طور پر بیماری کی چھٹی کا سرٹیفکیٹ پاس کرتے ہیں (اس کے بغیر یہ طریقہ کام نہیں کرے گا اور آپ کو کچھ بھی ادا نہیں کیا جائے گا!) ورک شیٹ کے طریقہ کار کے اندر، ضروری حسابات کیے جاتے ہیں (اکاؤنٹنٹ اسے استعمال کرتا ہے کہ کمپنی کو آپ کو کتنی رقم ادا کرنی چاہیے)، اور کام کا نتیجہ آپ کو واپس کر دیا جاتا ہے - رقم کی ایک رقم۔ پروگرام اسی طرح کام کرتا ہے۔ یہ ایک طریقہ کو کال کرتا ہے، وہاں ڈیٹا پاس کرتا ہے، اور آخر کار نتیجہ وصول کرتا ہے۔ main()ہمارے پروگرام کا طریقہ یہ ہے BridgeOfficer:
public static void main(String[] args) {
    Truck first = new Truck();
    first.weight = 10000;
    Truck second = new Truck();
    second.weight = 20000;

    BridgeOfficer officer = new BridgeOfficer(15000);
    System.out.println("Truck number 1! May I pass, officer?");
    boolean canFirstTruckGo = officer.checkTruck(first);
    System.out.println(canFirstTruckGo);

    System.out.println();

    System.out.println("Truck number 2! May I?");
    boolean canSecondTruckGo = officer.checkTruck(second);
    System.out.println(canSecondTruckGo);
}
ہم 10,000 اور 20,000 کے بوجھ کے ساتھ دو ٹرک بنا رہے ہیں۔ ایک ہی وقت میں، جس پل پر افسر ڈیوٹی پر ہوتا ہے اس کا زیادہ سے زیادہ وزن 15,000 ہوتا ہے۔ پروگرام کو طریقہ کہا جاتا ہے، طریقہ کار نے officer.checkTruck(first)ہر چیز کا حساب لگایا اور نتیجہ پروگرام کو واپس کر دیا۔ true، اور پروگرام نے اسے متغیر میں محفوظ کیا boolean canFirstTruckGo۔ اب وہ اس کے ساتھ جو چاہے کر سکتا ہے (جیسے آپ کو اکاؤنٹنٹ سے ملنے والی رقم سے)۔ بالآخر کوڈ
boolean canFirstTruckGo = officer.checkTruck(first);
تک نیچے آتا ہے
boolean canFirstTruckGo = true;
ایک بہت اہم نکتہ: آپریٹر returnنہ صرف طریقہ کار کا نتیجہ واپس کرتا ہے بلکہ اپنا کام بھی ختم کر دیتا ہے ! واپسی کے بعد لکھے گئے تمام کوڈ پر عمل نہیں کیا جائے گا!
public boolean checkTruck(Truck truck) {

    if (truck.weight > maxWeight) {
        return false;
        System.out.println("Turn around, overweight!");
    } else {
        return true;
        System.out.println("Alright, move on!");
    }
}
وہ جملے جو افسر کہتا ہے وہ کنسول میں آؤٹ پٹ نہیں ہوں گے، کیونکہ طریقہ پہلے ہی نتیجہ واپس کر چکا ہے اور اپنا کام مکمل کر چکا ہے! پروگرام اس مقام پر واپس آگیا جہاں طریقہ کہا گیا تھا۔ آپ کو خود اس کے بارے میں فکر کرنے کی ضرورت نہیں ہے - جاوا کمپائلر اتنا ہوشیار ہے کہ اگر آپ اس کے بعد کوڈ لکھنے کی کوشش کرتے ہیں تو غلطی پھینک سکتا ہے return۔

ایونجرز: آپشنز وار

ایسے حالات ہوتے ہیں جب ہمارے پروگرام کو طریقہ کار کے کام کرنے کے لیے متعدد اختیارات کی ضرورت ہوتی ہے۔ ہم اپنی مصنوعی ذہانت کیوں نہیں بنا لیتے؟ ایمیزون کے پاس الیکسا ہے، یانڈیکس کے پاس ایلس ہے، تو ہم کیوں بدتر ہیں؟ :) آئرن مین کے بارے میں فلم میں، ٹونی اسٹارک نے اپنی شاندار مصنوعی ذہانت تخلیق کی - JARVIS آئیے اس شاندار کردار کو خراج تحسین پیش کریں اور اپنے AI کا نام ان کے اعزاز میں رکھیں :) The سب سے پہلے ہمیں جارویس کو سکھانا چاہئے - کمرے میں داخل ہونے والے لوگوں کو سلام کرنا (یہ عجیب بات ہوگی کہ اگر اتنی بڑی عقل غیر اخلاقی نکلے)۔
public class Jarvis {

    public void sayHi(String name) {
        System.out.println("Good evening, " + name + ", How are you doing?");
    }

    public static void main(String[] args) {
        Jarvis jarvis = new Jarvis();
        jarvis.sayHi("Tony Stark");
    }
}
کنسول آؤٹ پٹ:
Добрый вечер, Тони Старк, How ваши дела?
زبردست! جارویس جانتا ہے کہ داخل ہونے والے کو کیسے سلام کرنا ہے۔ ٹونی سٹارک - زیادہ تر اکثر، کورس کے، یہ اس کے مالک ہو جائے گا. لیکن وہ اکیلا نہیں آسکتا! اور ہمارا طریقہ sayHi()ان پٹ کے طور پر صرف ایک دلیل لیتا ہے۔ اور اس کے مطابق وہ آنے والوں میں سے صرف ایک کو سلام کر سکے گا اور دوسرے کو نظر انداز کر دے گا۔ بہت شائستہ نہیں، متفق ہیں؟ :/ اس صورت میں، مسئلہ کو حل کرنے کے لیے، ہم کلاس میں صرف ایک ہی نام کے ساتھ 2 طریقے لکھ سکتے ہیں، لیکن مختلف پیرامیٹرز کے ساتھ:
public class Jarvis {

    public void sayHi(String firstGuest) {
        System.out.println("Good evening, " + firstGuest + ", How are you doing?");
    }

    public void sayHi(String firstGuest, String secondGuest) {
        System.out.println("Good evening, " + firstGuest + ", " + secondGuest + ", How are you doing?");
    }
}
اسے طریقہ اوورلوڈنگ کہا جاتا ہے ۔ اوورلوڈنگ ہمارے پروگرام کو زیادہ لچکدار بنانے اور کام کے مختلف اختیارات کو ایڈجسٹ کرنے کی اجازت دیتی ہے۔ آئیے چیک کریں کہ یہ کیسے کام کرتا ہے:
public class Jarvis {

    public void sayHi(String firstGuest) {
        System.out.println("Good evening, " + firstGuest + ", How are you doing?");
    }

    public void sayHi(String firstGuest, String secondGuest) {
        System.out.println("Good evening, " + firstGuest + ", " + secondGuest + ", How are you doing?");
    }

    public static void main(String[] args) {
        Jarvis jarvis = new Jarvis();
        jarvis.sayHi("Tony Stark");
        jarvis.sayHi("Tony Stark", "Captain America");
    }
}
کنسول آؤٹ پٹ:
Добрый вечер, Тони Старк, How ваши дела?
Добрый вечер, Тони Старк, Капитан Америка, How ваши дела?
بہت اچھا، دونوں اختیارات نے کام کیا :) تاہم، ہم نے مسئلہ حل نہیں کیا! اگر تین مہمان ہوں تو کیا ہوگا؟ بلاشبہ، ہم sayHi()تین مہمانوں کے ناموں کو قبول کرنے کے لیے دوبارہ طریقہ کو اوورلوڈ کر سکتے ہیں۔ لیکن ان میں سے 4 یا 5 ہو سکتے ہیں۔ اور اسی طرح اشتہار لامحدود۔ کیا جارویس کو کسی بھی تعداد کے ناموں کے ساتھ کام کرنا سکھانے کا کوئی اور طریقہ ہے، بغیر دس لاکھ طریقہ اوورلوڈ کے sayHi()؟ :/ یقینا ہے! دوسری صورت میں، کیا جاوا دنیا میں سب سے زیادہ مقبول پروگرامنگ زبان ہوگی؟ ;)
public void sayHi(String...names) {

    for (String name: names) {
        System.out.println("Good evening, " + name + ", How are you doing?");
    }
}
پیرامیٹر کے طور پر پاس کردہ ریکارڈ ( String...names) ہمیں اس بات کی نشاندہی کرنے کی اجازت دیتا ہے کہ اسٹرنگ کی ایک مخصوص تعداد طریقہ کو منتقل کی گئی ہے۔ ہم پہلے سے واضح نہیں کرتے ہیں کہ کتنے ہونے چاہئیں، لہذا ہمارے طریقہ کار کا عمل اب بہت زیادہ لچکدار ہو گیا ہے:
public class Jarvis {

    public void sayHi(String...names) {
        for (String name: names) {
            System.out.println("Good evening, " + name + ", How are you doing?");
        }
    }

    public static void main(String[] args) {
        Jarvis jarvis = new Jarvis();
        jarvis.sayHi("Tony Stark", "Captain America", "Black Widow", "Hulk");
    }
}
کنسول آؤٹ پٹ:
Добрый вечер, Тони Старк, How ваши дела?
Добрый вечер, Капитан Америка, How ваши дела?
Добрый вечер, Черная Вдова, How ваши дела?
Добрый вечер, Халк, How ваши дела?
یہاں کا کچھ کوڈ آپ کے لیے ناواقف ہے، لیکن اس پر کوئی اعتراض نہ کریں۔ اس کا جوہر آسان ہے - طریقہ کار تمام ناموں کے ذریعے جاتا ہے اور ہر ایک مہمان کو سلام کرتا ہے! مزید یہ کہ، یہ کسی بھی تعداد میں منتقل شدہ لائنوں کے لیے کام کرے گا! دو، دس، یہاں تک کہ ایک ہزار - طریقہ مہمانوں کی کسی بھی تعداد کے ساتھ قابل اعتماد طریقے سے کام کرے گا۔ تمام ممکنہ اختیارات کے لیے اوورلوڈ کرنے سے کہیں زیادہ آسان، کیا آپ متفق نہیں ہیں؟ :) ایک اور اہم نکتہ: دلائل کی ترتیب اہمیت رکھتی ہے! ہم کہتے ہیں کہ ہمارا طریقہ ان پٹ کے طور پر ایک تار اور ایک نمبر لیتا ہے:
public class Man {

    public static void sayYourAge(String greeting, int age) {
        System.out.println(greeting + " " + age);
    }

    public static void main(String[] args) {
        sayYourAge("My age - ", 33);
        sayYourAge(33, "My age - "); //error!
    }
}
اگر sayYourAgeکلاس کا طریقہ Manان پٹ کے طور پر سٹرنگ اور نمبر لیتا ہے، تو یہ وہ ترتیب ہے جس میں انہیں پروگرام میں پاس کرنے کی ضرورت ہے! اگر ہم ان کو مختلف ترتیب سے پاس کرتے ہیں تو مرتب کرنے والا غلطی کرے گا اور وہ شخص اپنی عمر نہیں بتا سکے گا۔ ویسے، ہم نے پچھلے لیکچر میں جن کنسٹرکٹرز کا احاطہ کیا تھا وہ بھی طریقے ہیں! انہیں اوورلوڈ بھی کیا جا سکتا ہے (دلائل کے مختلف سیٹوں کے ساتھ کئی کنسٹرکٹرز بنائیں) اور ان کے لیے آرگیومینٹس پاس کرنے کا آرڈر بھی بنیادی طور پر اہم ہے۔ حقیقی طریقے! :)

اور پھر پیرامیٹرز کے بارے میں

جی ہاں، ہم نے ابھی تک ان کے ساتھ کام نہیں کیا ہے :) اب ہم جس موضوع پر غور کریں گے وہ بہت اہم ہے۔ اس بات کا 90% امکان ہے کہ وہ آپ کے مستقبل کے تمام انٹرویوز میں اس بارے میں پوچھیں گے! ہم پیرامیٹرز کو طریقوں میں منتقل کرنے کے بارے میں بات کریں گے۔ آئیے ایک سادہ مثال دیکھیں:
public class TimeMachine {

    public void goToFuture(int currentYear) {
        currentYear = currentYear+10;
    }

    public void goToPast(int currentYear) {
        currentYear = currentYear-10;
    }

    public static void main(String[] args) {
        TimeMachine timeMachine = new TimeMachine();
        int currentYear = 2020;

        System.out.println("What is the year now?");
        System.out.println(currentYear);

        timeMachine.goToPast(currentYear);
        System.out.println("And now?");
        System.out.println(currentYear);
    }
}
ٹائم مشین کے دو طریقے ہیں۔ دونوں موجودہ سال کی نمائندگی کرنے والے ایک عدد کو ان پٹ کے طور پر لیتے ہیں اور یا تو قدر میں اضافہ یا کمی کرتے ہیں (اس بات پر منحصر ہے کہ ہم وقت پر واپس جانا چاہتے ہیں یا مستقبل میں)۔ لیکن، جیسا کہ کنسول آؤٹ پٹ سے دیکھا جا سکتا ہے، یہ طریقہ کارگر نہیں ہوا! کنسول آؤٹ پٹ:
Какой сейчас год?
2020
А сейчас?
2020
ہم نے ایک متغیر کو currentYearطریقہ میں منتقل کیا goToPast()، لیکن اس کی قدر میں کوئی تبدیلی نہیں آئی۔ جیسا کہ 2020 میں تھا، اب بھی ایسا ہی ہے۔ لیکن کیوں؟ :/ کیونکہ جاوا میں قدیم چیزوں کو قدر کے لحاظ سے طریقوں میں منتقل کیا جاتا ہے۔ اس کا کیا مطلب ہے؟ جب ہم کسی میتھڈ کو کال کرتے ہیں goToPast()اور وہاں اپنا ویری ایبل پاس کرتے ہیں int currentYear = 2020تو یہ متغیر خود میتھڈ میں نہیں آتا currentYearبلکہ اس کی ایک کاپی ہوتا ہے ۔ یقیناً اس کاپی کی قیمت بھی 2020 کے برابر ہے، لیکن کاپی میں ہونے والی تمام تبدیلیاں ہمارے اصل متغیر کو کسی بھی طرح متاثر نہیں کرتی ہیںcurrentYear ! آئیے اپنے کوڈ کو مزید لفظی بنائیں اور دیکھیں کہ اس کے ساتھ کیا ہوتا ہے currentYear:
public class TimeMachine {

    public void goToFuture(int currentYear) {
        currentYear = currentYear+10;
    }

    public void goToPast(int currentYear) {
        System.out.println("The goToPast method has started!");
        System.out.println("The currentYear value inside the goToPast method (at the beginning) = " + currentYear);
        currentYear = currentYear-10;
        System.out.println("The currentYear value inside the goToPast method (at the end) = " + currentYear);
    }

    public static void main(String[] args) {
        TimeMachine timeMachine = new TimeMachine();
        int currentYear = 2020;

        System.out.println("What is the year at the very beginning of the program?");
        System.out.println(currentYear);

        timeMachine.goToPast(currentYear);
        System.out.println("What year is it now?");
        System.out.println(currentYear);
    }
}
کنسول آؤٹ پٹ:
Какой год в самом начале работы программы?
2020
Метод goToPast начал работу!
Значение currentYear внутри метода goToPast (в начале) = 2020
Значение currentYear внутри метода goToPast (в конце) = 2010
А сейчас Howой год?
2020
یہ واضح طور پر ظاہر کرتا ہے کہ متغیر جو طریقہ کو منتقل کیا گیا تھا goToPast()وہ صرف ایک کاپی ہے currentYear۔ اور نقل کو تبدیل کرنے سے "اصل" کے معنی پر کوئی اثر نہیں ہوا۔ " حوالہ سے گزرنا " کے بالکل برعکس معنی ہیں۔ آئیے بلیوں پر مشق کریں! میرا مطلب ہے، آئیے دیکھتے ہیں کہ بلیوں کو بطور مثال استعمال کرتے ہوئے لنک سے گزرنا کیسا لگتا ہے :)
public class Cat {

    int age;

    public Cat(int age) {
        this.age = age;
    }
}
اب، اپنی ٹائم مشین کی مدد سے، ہم ماضی اور مستقبل میں دنیا کے پہلے بلی ٹائم ٹریولر Barsik کو لانچ کریں گے! آئیے کلاس کو تبدیل کریں TimeMachineتاکہ مشین اشیاء کے ساتھ کام کر سکے Cat۔
public class TimeMachine {

    public void goToFuture(Cat cat) {
        cat.age += 10;
    }

    public void goToPast(Cat cat) {
        cat.age -= 10;
    }
}
ageطریقے اب نہ صرف پاس شدہ نمبر کو تبدیل کرتے ہیں، بلکہ کسی مخصوص شے کی فیلڈ کو بھی تبدیل کرتے ہیں Cat۔ قدیم کے معاملے میں، جیسا کہ آپ کو یاد ہے، ہم کامیاب نہیں ہوئے: اصل نمبر تبدیل نہیں ہوا۔ دیکھتے ہیں یہاں کیا ہوتا ہے!
public static void main(String[] args) {

    TimeMachine timeMachine = new TimeMachine();
    Cat barsik = new Cat(5);

    System.out.println("How old is Barsik at the very beginning of the program?");
    System.out.println(barsik.age);

    timeMachine.goToFuture(barsik);
    System.out.println("And now?");
    System.out.println(barsik.age);

    System.out.println("Firs-sticks! Barsik has aged 10 years! Drive back quickly!");
    timeMachine.goToPast(barsik);
    System.out.println("Did it work? Have we returned the cat to its original age?");
    System.out.println(barsik.age);
}
کنسول آؤٹ پٹ:
Сколько лет Барсику в самом начале работы программы?
5
А теперь?
15
Елки-палки! Барсик постарел на 10 лет! Живо гони назад!
Получилось? Мы вернули коту его изначальный возраст?
5
زبردست! اب طریقہ مختلف طریقے سے کام کرتا ہے: ہماری بلی اچانک بوڑھی ہو گئی، اور پھر دوبارہ جوان نظر آنے لگی! :) آئیے اس کی وجہ جاننے کی کوشش کرتے ہیں۔ پرائمیٹوز کے ساتھ مثال کے برعکس، اشیاء کے معاملے میں آبجیکٹ کا حوالہ طریقہ پر منتقل کیا جاتا ہے۔ ہمارے اصل اعتراض کا حوالہ طریقوں goToFuture(barsik)کو دیا گیا تھا ۔ اس لیے، جب ہم اندر کے طریقے بدلتے ہیں ، تو ہم میموری کے اس حصے تک رسائی حاصل کرتے ہیں جہاں ہمارا آبجیکٹ محفوظ ہوتا ہے۔ یہ اسی بارسیک کی ایک کڑی ہے جسے ہم نے شروع ہی میں بنایا تھا۔ اسے کہتے ہیں "حوالہ سے گزرنا"! تاہم، ان لنکس کے ساتھ سب کچھ اتنا آسان نہیں ہے :) آئیے اپنی مثال کو تبدیل کرنے کی کوشش کریں: goToPast(barsik)barsikbarsik.age
public class TimeMachine {

    public void goToFuture(Cat cat) {
        cat = new Cat(cat.age);
        cat.age += 10;
    }

    public void goToPast(Cat cat) {
        cat = new Cat(cat.age);
        cat.age -= 10;
    }

    public static void main(String[] args) {
        TimeMachine timeMachine = new TimeMachine();
        Cat barsik = new Cat(5);

        System.out.println("How old is Barsik at the very beginning of the program?");
        System.out.println(barsik.age);

        timeMachine.goToFuture(barsik);
        System.out.println("Barsik went to the future! Has his age changed?");
        System.out.println(barsik.age);

        System.out.println("And if you try in the past?");
        timeMachine.goToPast(barsik);
        System.out.println(barsik.age);
    }
}
کنسول آؤٹ پٹ:
Сколько лет Барсику в самом начале работы программы?
5
Барсик отправился в будущее! Его возраст изменился?
5
А если попробовать в прошлое?
5
دوبارہ کام نہیں کرتا! O_O آئیے معلوم کریں کہ کیا ہوا :) یہ سب کچھ طریقوں goToPast/ goToFutureاور میکانکس کے بارے میں ہے کہ لنکس کیسے کام کرتے ہیں۔ اب توجہ!یہ نکتہ یہ سمجھنے میں سب سے اہم ہے کہ روابط اور طریقے کیسے کام کرتے ہیں۔ درحقیقت، جب ہم کسی طریقہ کو کہتے ہیں، goToFuture(Cat cat)تو یہ آبجیکٹ کا حوالہ نہیں ہوتا جو اس تک پہنچایا جاتا ہے cat، بلکہ اس حوالہ کی ایک نقل۔ یعنی، جب ہم کسی چیز کو کسی طریقہ پر منتقل کرتے ہیں، تو اس چیز کے دو حوالے ہوتے ہیں ۔ یہ سمجھنے کے لیے بہت ضروری ہے کہ کیا ہو رہا ہے۔ آخر کار یہی وجہ ہے کہ ہماری آخری مثال نے بلی کی عمر میں کوئی تبدیلی نہیں کی۔ عمر کو تبدیل کرنے کے ساتھ پچھلی مثال میں، ہم نے صرف طریقہ کے اندر پاس شدہ حوالہ لیا goToFuture()، اسے استعمال کرتے ہوئے میموری میں آبجیکٹ پایا اور اس کی عمر ( cat.age += 10) کو تبدیل کیا۔ اب طریقہ کے اندر goToFuture()ہم ایک نئی آبجیکٹ بناتے ہیں۔
(cat = new Cat(cat.age)),
اور وہی کاپی لنک جو طریقہ کو دیا گیا تھا اس آبجیکٹ کو تفویض کیا گیا ہے۔ اس کے نتیجے میں:
  • پہلا لنک ( Cat barsik = new Cat(5)) اصل بلی کی طرف اشارہ کرتا ہے (5 سال کی عمر کے ساتھ)
  • جب ہم نے متغیر کو catطریقہ کار میں منتقل کیا goToPast(Cat cat)اور اسے ایک نئی آبجیکٹ کو تفویض کیا تو حوالہ کاپی کر لیا گیا۔
اس کے بعد، ہمارے پاس حتمی صورت حال ہے: دو روابط دو مختلف اشیاء کی طرف اشارہ کرتے ہیں۔ لیکن ہم نے ان میں سے صرف ایک کی عمر کو تبدیل کیا - جسے ہم نے طریقہ کار کے اندر بنایا تھا۔
cat.age += 10;
اور قدرتی طور پر، جب ہم اسے طریقہ میں main()کنسول میں آؤٹ پٹ کرتے ہیں barsik.age، تو ہم دیکھتے ہیں کہ اس کی عمر میں کوئی تبدیلی نہیں آئی ہے۔ سب کے بعد barsik، یہ ایک حوالہ متغیر ہے جو اب بھی 5 سال کی عمر کے ساتھ پرانی، اصل چیز کی طرف اشارہ کرتا ہے، جس پر کچھ نہیں ہوا۔ عمر کے ساتھ ہماری تمام ہیرا پھیری ایک نئی چیز پر کی گئی تھی۔ اس طرح، یہ پتہ چلتا ہے کہ اشیاء کو حوالہ کے ذریعہ طریقوں میں منتقل کیا جاتا ہے. اشیاء کی کاپیاں کبھی خود بخود نہیں بنتی ہیں۔ اگر آپ نے کسی بلی کو کسی طریقہ پر اعتراض کیا اور اس کی عمر کو تبدیل کیا تو یہ کامیابی سے بدل جائے گی۔ لیکن حوالہ متغیر کی اقدار کو تفویض کرنے اور/یا کال کرنے کے طریقوں کو کاپی کیا جاتا ہے! آئیے یہاں پرائمیٹوز کو پاس کرنے کے بارے میں پیراگراف کو دہراتے ہیں: "جب ہم کسی طریقہ کو کال کرتے ہیں changeInt()اور وہاں اپنا متغیر پاس کرتے ہیں ، تو یہ متغیر خود نہیں ہوتاint x = 15 ہے جو طریقہ میں آتا ہے x، بلکہ اس کی نقل ۔ ہمارے اصل متغیر کو کسی بھی طرح متاثر کریں x۔ لنکس کاپی کرنے کے ساتھ، سب کچھ بالکل ایک جیسا کام کرتا ہے! آپ بلی اعتراض کو طریقہ پر منتقل کرتے ہیں۔ اگر آپ خود بلی کے ساتھ کچھ کرتے ہیں (یعنی میموری میں موجود شے کے ساتھ)، تو تمام تبدیلیاں کامیابی سے گزر جائیں گی - ہمارے پاس صرف ایک چیز تھی اور اب بھی ہے۔ لیکن اگر کسی طریقہ کے اندر آپ ایک نئی آبجیکٹ بناتے ہیں اور اسے ایک حوالہ متغیر میں محفوظ کرتے ہیں، جو کہ طریقہ کار کا ایک پیرامیٹر ہے، تو اب سے ہمارے پاس دو آبجیکٹ اور دو حوالہ متغیر ہیں۔ بس! یہ اتنا آسان نہیں تھا، آپ کو کئی بار لیکچر بھی دینا پڑ سکتا ہے۔ لیکن اصل بات یہ ہے کہ آپ نے یہ انتہائی اہم موضوع سیکھ لیا ہے۔ آپ کو اکثر دلائل کا سامنا کرنا پڑے گا (یہاں تک کہ تجربہ کار ڈویلپرز کے درمیان بھی) کہ جاوا میں دلائل کیسے پاس کیے جاتے ہیں۔ اب آپ جانتے ہیں کہ یہ کیسے کام کرتا ہے۔ اسے جاری رکھیں! :)
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION