JavaRush /جاوا بلاگ /Random-SD /طريقا، انهن جا پيرا ميٽر، رابطي ۽ اوورلوڊنگ

طريقا، انهن جا پيرا ميٽر، رابطي ۽ اوورلوڊنگ

گروپ ۾ شايع ٿيل
هڪ ڀيرو ٻيهر ڀليڪار! آخري ليڪچر ۾، اسان ڪلاسن ۽ تعمير ڪندڙن سان واقف ٿياسين، ۽ سکيوسين ته ڪيئن پنهنجو پاڻ ٺاهيو. طريقا، انهن جا پيرا ميٽر، رابطي ۽ اوورلوڊنگ - 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);
}
اسان 10000 ۽ 20000 جي لوڊ سان ٻه ٽرڪون ٺاهي رهيا آهيون، هڪ ئي وقت، جنهن پل تي آفيسر ڊيوٽي تي آهي، ان لاءِ وڌ ۾ وڌ وزن 15000 آهي، پروگرام کي ميٿڊ سڏيو ويو، طريقي سان 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.

Avengers: اختيارن جي جنگ

اهڙيون حالتون آهن جڏهن اسان جي پروگرام کي ڪيترن ئي اختيارن جي ضرورت آهي ته ڪيئن هڪ طريقو ڪم ڪري ٿو. اسان پنهنجي مصنوعي ذهانت ڇو نه ٺاهي؟ Amazon وٽ Alexa آهي، Yandex وٽ Alice آهي، پوءِ اسان ڇو خراب آهيون؟ :) آئرن مين جي باري ۾ فلم ۾، ٽوني اسٽارڪ پنهنجي شاندار مصنوعي ذهانت ٺاهي - JARVIS اچو ته شاندار ڪردار کي خراج تحسين پيش ڪريون ۽ اسان جي AI جو نالو سندس اعزاز ۾ رکون :) The پهرين شيء اسان کي Jarvis کي سيکارڻ گهرجي - ڪمري ۾ داخل ٿيڻ وارن ماڻهن کي سلام ڪريو (اهو عجيب ٿيندو جيڪڏهن اهڙي عظيم عقل بيوقوف ٿي وئي).
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 ٿي سگهن ٿا، وغيره وغيره. ڇا ھڪڙو ٻيو طريقو آھي جيڪو Jarvis کي سيکارڻ لاءِ ڪنھن نمبر جي نالن سان ڪم ڪرڻ لاءِ، ھڪڙي ملين طريقي جي اوور لوڊ کان سواءِ 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()۽ اتي پنهنجو variable پاس ڪندا آهيون 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;
    }
}
هاڻي، اسان جي ٽائم مشين جي مدد سان، اسان بارسڪ کي لانچ ڪنداسين، دنيا جي پهرين ٻلي-وقت مسافر، ماضي ۽ مستقبل ۾! اچو ته ڪلاس کي تبديل ڪريون TimeMachineته جيئن مشين شين سان ڪم ڪري سگهي Cat.
public class TimeMachine {

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

    public void goToPast(Cat cat) {
        cat.age -= 10;
    }
}
ageطريقا هاڻي نه رڳو منظور ٿيل نمبر، پر هڪ مخصوص اعتراض جي فيلڊ کي تبديل ڪن ٿا Cat. primitives جي صورت ۾، جيئن توهان کي ياد آهي، اسان ڪامياب نه ٿيا: اصل نمبر تبديل نه ڪيو. اچو ته ڏسون هتي ڇا ٿو ٿئي!
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
واهه! ھاڻي طريقو مختلف طرح سان ڪم ڪيو: اسان جي ٻلي اوچتو عمر ۾، ۽ پوء وري جوان ٿي ڏٺو! :) اچو ته معلوم ڪرڻ جي ڪوشش ڇو. primitives سان مثال جي برعڪس، شين جي صورت ۾ اعتراض جو حوالو طريقو ڏانهن منتقل ڪيو ويو آهي. اسان جي اصل اعتراض جو حوالو طريقن 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()۽ اُتي پنهنجو variable پاس ڪريون ٿا int x = 15، ته اهو پاڻ متغير نه آهي جيڪو ميٿڊ ۾ اچي ٿو x، پر ان جي ڪاپي . آخرڪار، ڪاپي ۾ جيڪي به تبديليون ٿين ٿيون، سي نه ٿيون ٿين. اسان جي اصل متغير کي ڪنهن به طريقي سان متاثر ڪيو x. لنڪس کي نقل ڪرڻ سان، هر شيء بلڪل ساڳيو ڪم ڪري ٿو! توهان طريقو کي ٻلي اعتراض پاس. جيڪڏهن توهان ٻلي سان گڏ ڪجهه ڪريو ٿا (يعني ياداشت ۾ اعتراض سان)، سڀ تبديليون ڪاميابيء سان ٿينديون - اسان وٽ صرف هڪ اعتراض هو ۽ اڃا تائين آهي. پر جيڪڏهن ڪنهن طريقي جي اندر توهان هڪ نئون اعتراض ٺاهيو ۽ ان کي هڪ ريفرنس ويريبل ۾ محفوظ ڪيو، جيڪو طريقو جو هڪ پيراميٽر آهي، هاڻي اسان وٽ ٻه شيون ۽ ٻه حوالا متغير آهن. اهو ئي سڀ ڪجهه آهي! اهو ايترو آسان نه هو، شايد توهان کي ڪيترائي ڀيرا ليڪچر ڏيڻو پوندو. پر بنيادي شيء اها آهي ته توهان هن سپر اهم موضوع کي سکيو آهي. توهان اڪثر دليلن سان منهن ڪندا (جيتوڻيڪ تجربيڪار ڊولپرز جي وچ ۾) جاوا ۾ دليل ڪيئن گذريا آهن. هاڻي توهان ڄاڻو ٿا ته اهو ڪيئن ڪم ڪري ٿو. جاري رکو! :)
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION