Halo lagi! Dalam pelajaran terakhir kami berkenalan dengan kelas dan konstruktor, dan belajar cara membuatnya sendiri. Hari ini kita akan lebih mengenal Metode Java, bagian penting dari kelas. Metode di Java adalah sekumpulan perintah yang memungkinkan Anda melakukan operasi tertentu dalam suatu program. Dengan kata lain, sebuah metode adalah sebuah fungsi; sesuatu yang dapat dilakukan oleh kelas Anda. Dalam bahasa pemrograman lain, metode sering disebut "fungsi", tetapi dalam Java kata "metode" lebih sering digunakan. :) Jika Anda ingat, di pelajaran terakhir kami membuat metode sederhana untuk kelas Kucing , sehingga kucing kami bisa berkata mengeong dan melompat:
public class Cat {
String name;
int age;
public void sayMeow() {
System.out.println("Meow!");
}
public void jump() {
System.out.println("Pounce!");
}
public static void main(String[] args) {
Cat smudge = new Cat();
smudge.age = 3;
smudge.name = "Smudge";
smudge.sayMeow();
smudge.jump();
}
}
sayMeow() dan jump() adalah metode kelas kami. Dan menjalankan metode ini menghasilkan keluaran konsol berikut:
Meow!
Pounce!
Metode kami cukup sederhana: mereka hanya menampilkan teks ke konsol. Namun di Java, metode memiliki tugas penting: mereka melakukan tindakan pada data objek. Mereka mengubah data objek, mengubahnya, menampilkannya, dan melakukan hal lain dengannya. Metode kami saat ini tidak melakukan apa pun dengan data objek Cat . Mari kita lihat contoh yang lebih ilustratif:
public class Truck {
int length;
int width;
int height;
int weight;
public int getVolume() {
int volume = length * width * height;
return volume;
}
}
Sebagai contoh, di sini kita memiliki sebuah kelas yang mewakili sebuah Truck . Truk semi memiliki panjang, lebar, tinggi, dan berat (yang akan kita butuhkan nanti). Dalam metode getVolume() , kami melakukan perhitungan, mengubah data objek kami menjadi angka yang mewakili volumenya (kami mengalikan panjang, lebar, dan tinggi). Angka ini akan menjadi hasil dari metode tersebut. Perhatikan bahwa deklarasi metode ditulis sebagai public int getVolume . Artinya, metode ini harus mengembalikan int . Kita menghitung nilai pengembalian metode, dan sekarang kita harus mengembalikannya ke program yang memanggil metode kita. Untuk mengembalikan hasil metode di Java, kami menggunakan kata kunci return. volume pengembalian;
Parameter Metode Java
Kita dapat meneruskan nilai yang disebut "argumen" ke suatu metode saat memanggilnya. Deklarasi sebuah metode menyertakan daftar variabel yang memberi tahu kita jenis dan urutan variabel yang dapat diterima metode tersebut. Daftar ini disebut "parameter metode". Metode getVolume() kelas Truk kita saat ini tidak menentukan parameter apa pun, jadi mari kita coba memperluas contoh truk kita. Buat kelas baru bernama BridgeOfficer . Ini adalah petugas polisi yang bertugas di sebuah jembatan, yang memeriksa semua truk yang lewat untuk melihat apakah muatannya melebihi 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 checkTruck menerima satu argumen, objek Truck , dan menentukan apakah petugas akan mengizinkan truk di anjungan atau tidak. Di dalam metode, logikanya cukup sederhana: jika berat truk melebihi batas maksimum yang diperbolehkan, maka metode mengembalikan false . Itu harus mencari jalan lain :( Jika beratnya kurang dari atau sama dengan maksimum, itu bisa lewat, dan metodenya kembali benar. Jika Anda belum sepenuhnya memahami frasa "mengembalikan" atau "metode mengembalikan nilai", mari kita berhenti sejenak dari pemrograman dan mempertimbangkannya menggunakan contoh sederhana dari kehidupan nyata. :) Katakanlah Anda sakit dan tinggal di rumah dari pekerjaan selama beberapa hari. Anda pergi ke departemen akuntansi dengan catatan dokter Anda, karena cuti sakit seharusnya dibayar. Jika kita membandingkan situasi ini dengan metode, maka akuntan memiliki paySickLeave ()metode. Anda memberikan catatan dokter sebagai argumen untuk metode ini (tanpanya, metode ini tidak akan berhasil dan Anda tidak akan dibayar!). Kemudian perhitungan yang diperlukan dibuat di dalam metode menggunakan catatan Anda (akuntan menggunakannya untuk menghitung berapa banyak perusahaan harus membayar Anda), dan hasil pekerjaan Anda (sejumlah uang) dikembalikan kepada Anda. Program kami bekerja dengan cara yang sama. Itu memanggil metode, meneruskan data ke sana, dan akhirnya menerima hasilnya. Inilah metode main() program BridgeOfficer kami :
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 1! Can I go, officer?");
boolean canFirstTruckGo = officer.checkTruck(first);
System.out.println(canFirstTruckGo);
System.out.println();
System.out.println("Truck 2! And can I?");
boolean canSecondTruckGo = officer.checkTruck(second);
System.out.println(canSecondTruckGo);
}
Kami membuat dua truk dengan muatan 10.000 dan 20.000. Dan jembatan tempat petugas bekerja memiliki bobot maksimal 15.000. Program memanggil metode officer.checkTruck(first) . Metode menghitung semuanya dan kemudian mengembalikan true , yang kemudian disimpan oleh program dalam variabel boolean canFirstTruckGo . Sekarang Anda dapat melakukan apa pun yang Anda inginkan dengannya (sama seperti Anda dapat menggunakan uang yang diberikan akuntan kepada Anda). Pada akhirnya, kodenya
boolean canFirstTruckGo = officer.checkTruck(first);
bermuara pada
boolean canFirstTruckGo = true;
Inilah poin yang sangat penting: pernyataan return tidak hanya mengembalikan nilai pengembalian metode, tetapi juga menghentikan metode agar tidak berjalan! Kode apa pun yang muncul setelah pernyataan pengembalian tidak akan dieksekusi!
public boolean checkTruck(Truck truck) {
if (truck.weight > maxWeight) {
return false;
System.out.println("Turn around, you're overweight!");
} else {
return true;
System.out.println("Everything looks good, go ahead!");
}
}
Komentar petugas tidak akan ditampilkan, karena metode tersebut telah mengembalikan hasil dan dihentikan! Program kembali ke tempat metode dipanggil. Anda tidak perlu memperhatikan hal ini: compiler Java cukup cerdas untuk menghasilkan kesalahan saat Anda mencoba menulis kode setelah pernyataan return .
Avengers: Perang Parameter
Ada situasi ketika kita menginginkan beberapa cara untuk memanggil sebuah metode. Mengapa tidak membuat kecerdasan buatan kita sendiri? Amazon punya Alexa, Apple punya Siri, jadi mengapa kita tidak punya? :) Dalam film Iron Man, Tony Stark menciptakan kecerdasan buatannya sendiri yang luar biasa, Jarvis. Mari beri penghormatan untuk karakter luar biasa itu dan beri nama AI kita untuk menghormatinya. :) Hal pertama yang perlu kita lakukan adalah mengajari Jarvis untuk menyapa orang yang memasuki ruangan (akan aneh jika kecerdasan yang luar biasa ternyata tidak sopan).
public class Jarvis {
public void sayHi(String name) {
System.out.println("Good evening, " + name + ". How are you?");
}
public static void main(String[] args) {
Jarvis jarvis = new Jarvis();
jarvis.sayHi("Tony Stark");
}
}
Keluaran konsol:
Good evening, Tony Stark. How are you?
Sangat bagus! Jarvis sekarang bisa menyambut tamu. Tentu saja, paling sering itu adalah tuannya, Tony Stark. Tetapi bagaimana jika dia tidak datang sendiri! Metode sayHi() kami hanya menerima satu argumen. Sehingga hanya bisa menyapa satu orang yang memasuki ruangan, dan akan mengabaikan yang lain. Tidak terlalu sopan, tidakkah Anda setuju? :/
Kelebihan Metode Java
Dalam hal ini, kita dapat menyelesaikan masalah hanya dengan menulis 2 metode dengan nama yang sama, tetapi parameter berbeda:
public class Jarvis {
public void sayHi(String firstGuest) {
System.out.println("Good evening, " + firstGuest + ". How are you?");
}
public void sayHi(String firstGuest, String secondGuest) {
System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
}
}
Ini disebut metode overloading. Kelebihan metode membuat program kita lebih fleksibel dan mengakomodasi berbagai cara kerja. Mari tinjau cara kerjanya:
public class Jarvis {
public void sayHi(String firstGuest) {
System.out.println("Good evening, " + firstGuest + ". How are you?");
}
public void sayHi(String firstGuest, String secondGuest) {
System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
}
public static void main(String[] args) {
Jarvis jarvis = new Jarvis();
jarvis.sayHi("Tony Stark");
jarvis.sayHi("Tony Stark", "Captain America");
}
}
Keluaran konsol:
Good evening, Tony Stark. How are you?
Good evening, Tony Stark and Captain America. How are you?
Luar biasa, kedua versi berfungsi. :) Tapi kami tidak menyelesaikan masalah! Bagaimana jika ada tiga tamu? Kita bisa, tentu saja, membebani metode sayHi() lagi, sehingga menerima tiga nama tamu. Tapi mungkin ada 4 atau 5. Hingga tak terhingga. Apakah tidak ada cara yang lebih baik untuk mengajari Jarvis menangani sejumlah nama, tanpa membebani metode sayHi() jutaan kali? :/ Tentu saja ada! Jika tidak ada, menurut Anda 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?");
}
}
Ketika ( String... nama ) digunakan sebagai parameter, ini menunjukkan bahwa kumpulan String akan diteruskan ke metode. Kami tidak harus menentukan sebelumnya berapa banyak yang akan ada, jadi sekarang metode kami jauh lebih fleksibel:
public class Jarvis {
public void sayHi(String...names) {
for (String name: names) {
System.out.println("Good evening, " + name + ". How are you?");
}
}
public static void main(String[] args) {
Jarvis jarvis = new Jarvis();
jarvis.sayHi("Tony Stark", "Captain America", "Black Widow", "Hulk");
}
}
Keluaran konsol:
Good evening, Tony Stark. How are you?
Good evening, Captain America. How are you?
Good evening, Black Widow. How are you?
Good evening, Hulk. How are you?
Beberapa kode di sini tidak akan Anda kenal, tetapi jangan khawatir. Intinya sederhana: metode ini mengambil setiap nama secara bergantian dan menyapa setiap tamu! Plus, itu akan bekerja dengan sejumlah string yang diteruskan! Dua, sepuluh, bahkan seribu—metode ini akan bekerja dengan baik dengan jumlah tamu berapa pun. Jauh lebih nyaman daripada membebani metode untuk semua kemungkinan, bukan begitu? :) Inilah poin penting lainnya: urutan argumen itu penting! Katakanlah metode kita menggunakan sebuah String dan sebuah angka:
public class Person {
public static void sayYourAge(String greeting, int age) {
System.out.println(greeting + " " + age);
}
public static void main(String[] args) {
sayYourAge("My age is ", 33);
sayYourAge(33, "My age is "); // Error!
}
}
Jika metode sayYourAge kelas Person mengambil string dan angka sebagai input, maka program harus meneruskannya dalam urutan tertentu! Jika kita meneruskannya dalam urutan yang berbeda, kompiler akan menghasilkan kesalahan dan orang tersebut tidak akan dapat menyebutkan usianya. Ngomong-ngomong, konstruktor, yang kita bahas di pelajaran terakhir, juga merupakan metode! Anda juga dapat membebani mereka (yaitu membuat beberapa konstruktor dengan kumpulan parameter yang berbeda) dan urutan argumen yang diteruskan pada dasarnya juga penting bagi mereka. Itu adalah metode nyata! :)
Lagi-lagi mengenai parameter
Ya, maaf, kami belum selesai dengan mereka. :) Topik yang akan kita pelajari sekarang sangat penting. Ada kemungkinan 90% Anda akan ditanyai tentang hal ini di setiap wawancara mendatang! Mari kita bicara tentang meneruskan argumen ke metode. Pertimbangkan 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 = 2018;
System.out.println("What year is it?");
System.out.println(currentYear);
timeMachine.goToPast(currentYear);
System.out.println("How about now?");
System.out.println(currentYear);
}
}
Mesin waktu memiliki dua metode. Mereka berdua mengambil angka yang mewakili tahun ini sebagai input, dan menambah atau mengurangi nilainya (tergantung apakah kita ingin pergi ke masa lalu atau masa depan). Tapi, seperti yang Anda lihat dari keluaran konsol, metode ini tidak berfungsi! Keluaran konsol:
What year is it?
2018
How about now?
2018
Kami meneruskan variabel currentYear ke metode goToPast() , tetapi nilainya tidak berubah. Kami berada di tahun 2018, dan di sini kami tetap tinggal. Tapi kenapa? :/ Karena primitif di Java diteruskan ke metode berdasarkan nilai. Maksudnya itu apa? Saat kita memanggil metode goToPast() dan meneruskan variabel int currentYear (=2018) ke dalamnya, metode tersebut tidak mendapatkan variabel currentYear itu sendiri, melainkan salinannya. Tentu saja, nilai dari salinan ini juga 2018, tetapi perubahan apa pun pada salinan tersebut tidak memengaruhi variabel CurrentYear asli kami dengan cara apa pun! Mari buat kode kita lebih eksplisit 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 running!");
System.out.println("currentYear inside the goToPast method (at the beginning) = " + currentYear);
currentYear = currentYear-10;
System.out.println("currentYear inside the goToPast method (at the end) = " + currentYear);
}
public static void main(String[] args) {
TimeMachine timeMachine = new TimeMachine();
int currentYear = 2018;
System.out.println("What was the year when the program started?");
System.out.println(currentYear);
timeMachine.goToPast(currentYear);
System.out.println("And what year is it now?");
System.out.println(currentYear);
}
}
Keluaran konsol:
What was the year when the program started?
2018
The goToPast method has started running!
currentYear inside the goToPast method (at the beginning) = 2018
currentYear inside the goToPast method (at the end) = 2008
And what year is it now?
2018
Ini dengan jelas menunjukkan bahwa variabel yang diteruskan ke metode goToPast() hanyalah salinan dari currentYear . Dan mengubah salinan tidak memengaruhi nilai "asli". "Lewati referensi" berarti sebaliknya. Mari berlatih pada kucing! Maksud saya, mari kita lihat seperti apa referensi lewat menggunakan contoh kucing. :)
public class Cat {
int age;
public Cat(int age) {
this.age = age;
}
}
Sekarang dengan bantuan mesin waktu kami, kami akan mengirim Smudge , kucing penjelajah waktu pertama di dunia, ke masa lalu dan masa depan! Mari kita modifikasi kelas TimeMachine agar bekerja dengan objek Cat ;
public class TimeMachine {
public void goToFuture(Cat cat) {
cat.age += 10;
}
public void goToPast(Cat cat) {
cat.age -= 10;
}
}
Sekarang metode tidak hanya mengubah nomor yang dikirimkan. Sebaliknya, mereka mengubah bidang usia Kucing tertentu itu . Anda akan ingat bahwa ini tidak berhasil untuk kami dengan primitif, karena nomor aslinya tidak berubah. Mari kita lihat apa yang akan terjadi!
public static void main(String[] args) {
TimeMachine timeMachine = new TimeMachine();
Cat smudge = new Cat(5);
System.out.println("How old was Smudge when the program started?");
System.out.println(smudge.age);
timeMachine.goToFuture(smudge);
System.out.println("How about now?");
System.out.println(smudge.age);
System.out.println("Holy smokes! Smudge has aged 10 years! Back up quickly!");
timeMachine.goToPast(smudge);
System.out.println("Did it work? Have we returned the cat to its original age?");
System.out.println(smudge.age);
}
Keluaran konsol:
How old was Smudge when the program started running?
5
How about now?
15
Holy smokes! Smudge has aged 10 years! Back up quickly!
Did it work? Have we returned the cat to its original age?
5
Wow! Sekarang metodenya melakukan sesuatu yang berbeda: kucing kami menua secara drastis, tetapi kemudian menjadi muda kembali! :) Mari kita coba cari tahu alasannya. Berbeda dengan contoh dengan primitif, ketika objek diteruskan ke metode, mereka diteruskan dengan referensi. Referensi ke objek noda asli diteruskan ke metode changeAge() . Jadi, saat kita mengubah smudge.age di dalam metode, kita mereferensikan area memori yang sama tempat objek kita disimpan. Ini referensi ke Smudge yang sama yang kami buat pada awalnya. Ini disebut "melewati referensi"! Namun, tidak semua yang memiliki referensi semudah itu. :) Mari coba ubah contoh kita:
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 smudge = new Cat(5);
System.out.println("How old was Smudge when the program started?");
System.out.println(smudge.age);
timeMachine.goToFuture(smudge);
System.out.println ("Smudge went to the future! Has his age changed?");
System.out.println(smudge.age);
System.out.println ("And if you try going back?");
timeMachine.goToPast(smudge);
System.out.println(smudge.age);
}
}
Keluaran konsol:
How old was Smudge when the program started running?
5
Smudge went to the future! Has his age changed?
5
And if you try going back?
5
Itu tidak bekerja lagi! О_О Mari cari tahu apa yang terjadi. :) Ini ada hubungannya dengan metode goToPast / goToFuture dan cara kerja referensi. Sekarang, mohon perhatiannya! Ini adalah hal yang paling penting untuk dipahami tentang bagaimana referensi dan metode bekerja. Faktanya adalah, ketika kita memanggil metode goToFuture(Cat cat) , itu adalah salinan referensi ke objek cat yang diteruskan, bukan referensi itu sendiri. Jadi, ketika kita melewatkan sebuah objek ke sebuah metode, ada dua referensi ke objek tersebut. Ini sangat penting untuk memahami apa yang terjadi. Inilah mengapa usia kucing tidak berubah dalam contoh terakhir kita. Pada contoh sebelumnya, saat mengubah usia, kami cukup mengambil referensi yang diteruskan ke goToFuture ()metode, dan menggunakannya untuk menemukan objek dalam memori dan mengubah umurnya ( cat.age += 10 ). Tapi sekarang, di dalam metode goToFuture() , kita membuat objek baru ( cat = new Cat(cat.age) ), dan objek ini diberi salinan referensi yang sama yang diteruskan ke metode. Sebagai akibat:
- Referensi pertama ( Cat smudge = Kucing baru (5) ) menunjuk ke kucing asli (dengan usia 5 tahun)
- Setelah itu, saat kami meneruskan variabel cat ke metode goToPast() dan memberinya objek baru, referensi disalin.
cat.age += 10;
Dan tentu saja, dalam metode main() kita dapat melihat di konsol bahwa umur kucing, smudge.age , tidak berubah. Lagi pula, corengan adalah variabel referensi yang masih menunjuk ke objek asli yang lama dengan usia 5 tahun, dan kami tidak melakukan apa pun dengan objek itu. Semua perubahan usia kami dilakukan pada objek baru. Jadi, ternyata objek diteruskan ke metode dengan referensi. Salinan objek tidak pernah dibuat secara otomatis. Jika Anda meneruskan objek kucing ke suatu metode dan mengubah umurnya, Anda akan mengubah umurnya. Tetapi variabel referensi disalin saat menetapkan nilai dan/atau memanggil metode! Mari kita ulangi di sini apa yang kita katakan tentang melewati primitif: "Ketika kita memanggil metode changeInt() dan meneruskan intvariabel x (=15) , metode ini tidak mendapatkan variabel x itu sendiri, melainkan salinannya. Oleh karena itu, setiap perubahan yang dibuat pada salinan tidak memengaruhi x asli kamiAnda masih akan berdebat lebih dari sekali tentang bagaimana argumen diteruskan di Jawa (bahkan di antara pengembang berpengalaman). Tapi, sekarang Anda tahu persis cara kerjanya. Lanjutkan kerja baikmu! :) Untuk memperkuat apa yang Anda pelajari, kami sarankan Anda menonton video pelajaran dari Kursus Java kami
Lebih banyak bacaan: |
---|
GO TO FULL VERSION