JavaRush /Java Blog /Random-ID /Metode, parameternya, interaksi dan kelebihan beban

Metode, parameternya, interaksi dan kelebihan beban

Dipublikasikan di grup Random-ID
Halo lagi! Pada kuliah terakhir, kita berkenalan dengan kelas dan konstruktor, dan belajar cara membuatnya sendiri. Metode, parameternya, interaksi dan kelebihan beban - 1Hari ini kita akan melihat lebih dekat bagian integral dari kelas seperti metode. Metode adalah sekumpulan perintah yang memungkinkan Anda melakukan beberapa operasi dalam suatu program. Dengan kata lain, metode adalah suatu fungsi; sesuatu yang dapat dilakukan kelas Anda. Dalam bahasa pemrograman lain, metode sering disebut “fungsi”, tetapi di Java kata “metode” menjadi lebih populer :) Pada kuliah terakhir, jika Anda ingat, kami membuat metode sederhana untuk kelas Cat agar kucing kami dapat mengeong dan melompat:
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()dan jump()merupakan metode kelas kita. Hasil kerja mereka adalah output ke konsol:
Мяу!
Прыг-скок!
Metode kami cukup sederhana: cukup mencetak teks ke konsol. Namun di Java, metode memiliki tugas utama - mereka harus melakukan tindakan pada data suatu objek . Ubah nilai data suatu objek, ubah, keluarkan ke konsol, atau lakukan hal lain dengannya. Metode kami saat ini tidak melakukan apa pun dengan data objek Cat. Mari kita lihat contoh yang lebih jelas:
public class Truck {

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

    public int getVolume() {
        int volume = length * width * height;
        return volume;
    }
}
Misalnya, kita mempunyai kelas yang mewakili truk - Truck. Trailer truk memiliki panjang, lebar dan tinggi, serta berat (ini akan diperlukan nanti). Dalam metode ini, getVolume()kami melakukan penghitungan - kami mengubah data objek kami menjadi angka yang menunjukkan volume (kami mengalikan panjang, lebar, dan tinggi). Ini adalah angka yang akan menjadi hasil dari metode tersebut. Harap dicatat - dalam deskripsi metode ada tertulis public int getVolume. Artinya, hasil dari cara ini harus berupa angka int. Kita telah menghitung hasil dari metode tersebut, dan sekarang kita harus mengembalikannya ke program kita yang memanggil metode tersebut. Untuk mengembalikan hasil suatu metode di Java, digunakan kata kunci return.
return volume;

Parameter metode

Metode dapat menerima nilai sebagai masukan, yang disebut "parameter metode". Metode kita saat ini getVolume()di kelas Trucktidak menerima parameter apa pun, jadi mari kita coba memperluas contoh dengan truk. Mari buat kelas baru - BridgeOfficer. Seorang petugas polisi bertugas di jembatan dan memeriksa semua truk yang lewat untuk memastikan muatannya tidak melebihi batas berat yang diperbolehkan.
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;
        }
    }
}
Metode tersebut checkTruckmengambil satu parameter sebagai masukan - objek truk Truck, dan menentukan apakah petugas akan mengizinkan truk tersebut masuk ke jembatan atau tidak. Logika di dalam metode ini cukup sederhana: jika berat truk melebihi batas maksimum yang diperbolehkan, metode akan mengembalikan false. Anda harus mencari jalan lain :( Jika bobotnya kurang dari atau sama dengan maksimum, Anda dapat melewatinya, dan metodenya kembali true. Jika Anda masih belum sepenuhnya memahami ungkapan “kembali”, “metode mengembalikan suatu nilai ” - mari kita istirahat dari pemrograman dan lihat ini menggunakan contoh sederhana dari kehidupan dunia nyata :) Katakanlah Anda sakit dan tidak bekerja selama beberapa hari. Anda datang ke departemen akuntansi dengan cuti sakit, yang harus Anda bayar. Jika kita analogikan dengan metode, maka akuntan memiliki metode paySickLeave()(“membayar cuti sakit”). Anda memberikan sertifikat cuti sakit ke metode ini sebagai parameter (tanpanya, metode ini tidak akan berfungsi dan Anda tidak akan dibayar apa pun!). Di dalam metode lembar kerja, perhitungan yang diperlukan dibuat (akuntan menggunakannya untuk menghitung berapa banyak perusahaan harus membayar Anda), dan hasil pekerjaan dikembalikan kepada Anda - sejumlah uang. Program ini bekerja dengan cara yang sama. Ia memanggil suatu metode, meneruskan data ke sana dan akhirnya menerima hasilnya. Berikut adalah metode main()untuk program kami 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);
}
Kami membuat dua truk dengan muatan 10.000 dan 20.000. Pada saat yang sama, berat maksimum untuk jembatan tempat petugas bertugas adalah 15.000. Program ini disebut metode officer.checkTruck(first), metode menghitung semuanya dan mengembalikan hasilnya ke program - true, dan program menyimpannya dalam variabel boolean canFirstTruckGo. Sekarang dia dapat melakukan apapun yang dia inginkan dengan uang itu (seperti Anda dengan uang yang Anda terima dari akuntan). Pada akhirnya kodenya
boolean canFirstTruckGo = officer.checkTruck(first);
turun ke
boolean canFirstTruckGo = true;
Poin yang sangat penting: operator returntidak hanya mengembalikan hasil metode, tetapi juga menghentikan pekerjaannya ! Semua kode yang ditulis setelah pengembalian tidak akan dieksekusi!
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!");
    }
}
Ungkapan yang diucapkan petugas tidak akan ditampilkan ke konsol, karena metode tersebut telah mengembalikan hasil dan menyelesaikan tugasnya! Program kembali ke titik di mana metode tersebut dipanggil. Anda tidak perlu mengkhawatirkan hal ini sendiri - kompiler Java cukup pintar untuk membuat kesalahan jika Anda mencoba menulis kode setelahnya return.

Avengers: Perang Pilihan

Ada situasi ketika program kita memerlukan beberapa opsi tentang cara kerja suatu metode. Mengapa kita tidak menciptakan kecerdasan buatan kita sendiri? Amazon punya Alexa, Yandex punya Alice, jadi mengapa kita lebih buruk? :) Dalam film tentang Iron Man, Tony Stark menciptakan kecerdasan buatannya yang luar biasa - JARVIS Mari kita memberi penghormatan kepada karakter yang luar biasa dan memberi nama AI kita untuk menghormatinya :) hal pertama yang harus kita ajarkan pada Jarvis adalah menyapa orang yang memasuki ruangan (akan aneh jika kecerdasan sebesar itu ternyata tidak sopan).
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");
    }
}
Keluaran konsol:
Добрый вечер, Тони Старк, How ваши дела?
Besar! Jarvis tahu bagaimana menyapa seseorang yang masuk. Paling sering, tentu saja, itu adalah pemiliknya - Tony Stark. Tapi dia mungkin tidak datang sendiri! Dan metode kami sayHi()hanya mengambil satu argumen sebagai masukan. Dan karenanya, dia hanya bisa menyapa salah satu dari mereka yang datang, dan mengabaikan yang lain. Tidak terlalu sopan, setuju? :/ Dalam hal ini, untuk menyelesaikan masalah, kita cukup menulis 2 metode di kelas dengan nama yang sama, tetapi dengan parameter berbeda:
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?");
    }
}
Ini disebut metode kelebihan beban . Kelebihan beban memungkinkan program kami menjadi lebih fleksibel dan mengakomodasi berbagai pilihan pekerjaan. Mari kita periksa cara kerjanya:
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");
    }
}
Keluaran konsol:
Добрый вечер, Тони Старк, How ваши дела?
Добрый вечер, Тони Старк, Капитан Америка, How ваши дела?
Hebat, kedua opsi berfungsi :) Namun, kami tidak menyelesaikan masalah! Bagaimana jika ada tiga tamu? Tentu saja kita bisa membebani metode itu lagi sayHi()untuk menerima nama ketiga tamu tersebut. Tapi bisa ada 4 atau 5. Dan seterusnya tanpa batas. Apakah ada cara lain untuk mengajari Jarvis bekerja dengan sejumlah nama, tanpa sejuta metode yang berlebihan sayHi()? :/ Tentu saja pernah! Jika tidak, apakah Java akan menjadi bahasa pemrograman paling populer di dunia? ;)
public void sayHi(String...names) {

    for (String name: names) {
        System.out.println("Good evening, " + name + ", How are you doing?");
    }
}
Catatan ( String...names) yang diteruskan sebagai parameter memungkinkan kita untuk menunjukkan bahwa sejumlah string tertentu diteruskan ke metode tersebut. Kami tidak menentukan terlebih dahulu berapa banyak yang harus ada, sehingga pengoperasian metode kami sekarang menjadi jauh lebih fleksibel:
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");
    }
}
Keluaran konsol:
Добрый вечер, Тони Старк, How ваши дела?
Добрый вечер, Капитан Америка, How ваши дела?
Добрый вечер, Черная Вдова, How ваши дела?
Добрый вечер, Халк, How ваши дела?
Beberapa kode di sini asing bagi Anda, tapi jangan pedulikan itu. Esensinya sederhana - metode ini menelusuri semua nama secara bergantian dan menyapa setiap tamu! Selain itu, ini akan berfungsi untuk sejumlah jalur yang ditransfer! Dua, sepuluh, bahkan seribu - metode ini akan bekerja dengan andal untuk sejumlah tamu berapa pun. Jauh lebih nyaman daripada melakukan kelebihan beban untuk semua opsi yang ada, setujukah Anda? :) Poin penting lainnya: urutan argumen itu penting! Katakanlah metode kita mengambil string dan angka sebagai masukan:
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!
    }
}
Jika metode sayYourAgekelas Manmengambil string dan angka sebagai input, maka ini adalah urutan yang harus diteruskan ke dalam program! Jika kita meneruskannya dalam urutan yang berbeda, kompiler akan memberikan kesalahan dan orang tersebut tidak akan dapat mengetahui usianya. Ngomong-ngomong, konstruktor yang kita bahas di kuliah terakhir juga merupakan metode! Mereka juga dapat kelebihan beban (membuat beberapa konstruktor dengan rangkaian argumen berbeda) dan bagi mereka urutan penyampaian argumen juga penting secara mendasar. Metode nyata! :)

Dan lagi tentang parameternya

Ya, ya, kita belum selesai dengan mereka :) Topik yang akan kita bahas sekarang sangatlah penting. Ada kemungkinan 90% mereka akan menanyakan hal ini pada semua wawancara Anda selanjutnya! Kita akan membahas tentang meneruskan parameter ke metode. Mari kita lihat contoh sederhana:
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);
    }
}
Mesin waktu memiliki dua metode. Keduanya mengambil masukan berupa angka yang mewakili tahun berjalan dan menambah atau mengurangi nilainya (tergantung apakah kita ingin kembali ke masa lalu atau ke masa depan). Namun, seperti yang terlihat dari keluaran konsol, metode ini tidak berhasil! Keluaran konsol:
Какой сейчас год?
2020
А сейчас?
2020
Kami meneruskan variabel currentYearke metode goToPast(), tetapi nilainya tidak berubah. Seperti pada tahun 2020, tetap demikian. Tapi kenapa? :/ Karena primitif di Java diteruskan ke metode berdasarkan nilai. Apa artinya? Ketika kita memanggil suatu metode goToPast()dan meneruskan variabel kita ke sana int currentYear = 2020, bukan variabel itu sendiri yang masuk ke dalam metode tersebut currentYear, melainkan salinannya . Nilai salinan ini tentu saja juga sama dengan 2020, tetapi semua perubahan yang terjadi pada salinan tersebut sama sekali tidak mempengaruhi variabel asli kitacurrentYear ! Mari buat kode kita lebih bertele-tele dan lihat apa yang terjadi dengan 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);
    }
}
Keluaran konsol:
Какой год в самом начале работы программы?
2020
Метод goToPast начал работу!
Значение currentYear внутри метода goToPast (в начале) = 2020
Значение currentYear внутри метода goToPast (в конце) = 2010
А сейчас Howой год?
2020
Ini jelas menunjukkan bahwa variabel yang diteruskan ke metode ini goToPast()hanyalah salinan currentYear. Dan mengubah salinannya tidak berpengaruh pada arti “asli”. " Melewati referensi " memiliki arti sebaliknya. Ayo berlatih pada kucing! Maksudku, mari kita lihat seperti apa lewat tautan dengan menggunakan kucing sebagai contoh :)
public class Cat {

    int age;

    public Cat(int age) {
        this.age = age;
    }
}
Sekarang, dengan bantuan mesin waktu kami, kami akan meluncurkan Barsik, penjelajah waktu kucing pertama di dunia, ke masa lalu dan masa depan! Mari kita ubah kelasnya TimeMachinesehingga mesin dapat bekerja dengan objek Cat;
public class TimeMachine {

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

    public void goToPast(Cat cat) {
        cat.age -= 10;
    }
}
Metode sekarang tidak hanya mengubah nomor yang diteruskan, tetapi juga bidang ageobjek tertentu Cat. Dalam kasus primitif, seperti yang Anda ingat, kami tidak berhasil: nomor aslinya tidak berubah. Mari kita lihat apa yang terjadi di sini!
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);
}
Keluaran konsol:
Сколько лет Барсику в самом начале работы программы?
5
А теперь?
15
Елки-палки! Барсик постарел на 10 лет! Живо гони назад!
Получилось? Мы вернули коту его изначальный возраст?
5
Wow! Sekarang metodenya bekerja secara berbeda: kucing kami tiba-tiba menjadi tua, dan kemudian tampak lebih muda lagi! :) Mari kita coba mencari tahu alasannya. Berbeda dengan contoh primitif, dalam kasus objek, referensi ke objek diteruskan ke metode. Referensi ke objek asli kami diteruskan goToFuture(barsik)ke metode . Oleh karena itu, ketika kita mengubah metode di dalam , kita mengakses area memori tempat objek kita disimpan. Ini adalah link ke Barsik yang sama yang kami buat di awal. Ini disebut "melewati referensi"! Namun, dengan tautan ini semuanya tidak sesederhana itu :) Mari kita coba ubah contoh kita: 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);
    }
}
Keluaran konsol:
Сколько лет Барсику в самом начале работы программы?
5
Барсик отправился в будущее! Его возраст изменился?
5
А если попробовать в прошлое?
5
Tidak berfungsi lagi! O_O Mari kita cari tahu apa yang terjadi :) Ini semua tentang metode goToPast/ goToFuturedan mekanisme cara kerja tautan. Sekarang perhatian!Poin ini adalah yang paling penting dalam memahami cara kerja tautan dan metode. Faktanya, ketika kita memanggil suatu metode, goToFuture(Cat cat)bukan referensi objek itu sendiri yang diteruskan ke metode tersebut cat, tetapi salinan dari referensi ini. Artinya, ketika kita meneruskan suatu objek ke suatu metode, ada dua referensi ke objek tersebut . Ini sangat penting untuk memahami apa yang sedang terjadi. Inilah sebabnya contoh terakhir kita tidak mengubah usia kucing. Pada contoh sebelumnya dengan mengubah umur, kita cukup mengambil referensi yang diteruskan di dalam metode goToFuture(), menemukan objek di memori menggunakannya dan mengubah umurnya ( cat.age += 10). Sekarang di dalam metode goToFuture()kita membuat objek baru
(cat = new Cat(cat.age)),
dan salinan tautan yang sama yang diteruskan ke metode tersebut ditetapkan ke objek ini. Sebagai akibat:
  • Tautan pertama ( Cat barsik = new Cat(5)) menunjuk ke kucing asli (dengan usia 5 tahun)
  • Setelah kita meneruskan variabel catke metode goToPast(Cat cat)dan menugaskannya ke objek baru, referensinya disalin.
Setelah ini, kita mendapatkan situasi terakhir: dua tautan menunjuk ke dua objek berbeda. Namun kami hanya mengubah usia salah satu dari mereka - usia yang kami buat di dalam metode.
cat.age += 10;
Dan tentu saja, ketika kita mengeluarkannya main()ke konsol dengan metode ini barsik.age, kita melihat bahwa umurnya tidak berubah. Bagaimanapun barsik, ini adalah variabel referensi yang masih menunjuk ke objek lama dan asli dengan usia 5 tahun, yang tidak terjadi apa-apa. Semua manipulasi kita seiring bertambahnya usia dilakukan pada objek baru. Jadi, ternyata objek diteruskan ke metode melalui referensi. Salinan objek tidak pernah dibuat secara otomatis. Jika Anda meneruskan objek kucing ke suatu metode dan mengubah umurnya, maka objek tersebut akan berhasil diubah. Tetapi nilai variabel referensi disalin saat menetapkan dan/atau memanggil metode! Mari kita ulangi di sini paragraf tentang meneruskan primitif: "Ketika kita memanggil suatu metode changeInt()dan meneruskan variabel kita di sana int x = 15, bukan variabel itu sendiri yang masuk ke dalam metode itu x, tetapi salinannya . Lagi pula, semua perubahan yang terjadi pada salinan tidak memengaruhi variabel asli kita dengan cara apa pun x.” Dengan menyalin tautan, semuanya bekerja persis sama! Anda meneruskan objek cat ke metode tersebut. Jika Anda melakukan sesuatu dengan kucing itu sendiri (yaitu, dengan objek di memori), semua perubahan akan berhasil - kami hanya memiliki satu objek dan masih memilikinya. Tetapi jika di dalam suatu metode Anda membuat objek baru dan menyimpannya dalam variabel referensi, yang merupakan parameter metode, mulai sekarang kita memiliki dua objek dan dua variabel referensi. Itu saja! Tidak semudah itu, bahkan mungkin harus beberapa kali ceramah. Namun yang terpenting adalah Anda telah mempelajari topik yang sangat penting ini. Anda akan sering menemukan argumen (bahkan di antara pengembang berpengalaman) tentang bagaimana argumen disampaikan di Java. Sekarang Anda tahu persis cara kerjanya. Lanjutkan kerja baikmu! :)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION