Metode
5.1 Introduksi
Dimisalkan Anda ingin mencari
penjumlahan integer, berturut-turut, dari 1 sampai 10, dari 20 sampai 30, dan
dari 35 sampai 45. Anda mungkin akan memiliki kode sebagai berikut:
int
jumlah = 0;
for
(int i = 1;
i <= 10; i++)
jumlah
+= i;
System.out.println("Jumlah
dari 1 sampai 10 adalah " + jumlah);
jumlah
= 0;
for
(int i = 20;
i <= 30; i++)
jumlah
+= i;
System.out.println("Jumlah
dari 20 sampai 30 adalah " + jumlah);
jumlah
= 0;
for
(int i = 35;
i <= 45; i++)
jumlah
+= i;
System.out.println("Jumlah
dari 35 sampai 45 adalah " + jumlah);
Anda dapat mengamati bahwa
menghitung penjumlahan integer dari 1 sampai 10, dari 20 sampai 30, dan dari 35
sampai 45 adalah sama kecuali bahwa integer awal dan integer akhir yang
berbeda. Apakah tidak lebih mudah bila suatu kode ditulis untuk melakukan
penjumlahan integer dan kemudian mendaur-ulangnya (menggunakannya kembali)
tanpa perlu menulis-ulangnya? Anda dapat melakukannya lewat pendefinisian
metode. Metode dibuat untuk menciptakan kode yang bisa didaur-ulang. Kode
sebelumnya dapat disederhanakan sebagai berikut:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public static int jumlah(int
i1, int i2) {
int jumlah = 0;
for (int i = i1; i <= i2; i++)
jumlah += i;
return jumlah;
}
public static void main(String[]
args) {
System.out.println("Jumlah dari 1 sampai 10 = " + jumlah(1,
10));
System.out.println("Jumlah dari 20 sampai 30 = " + jumlah(20,
30));
System.out.println("Jumlah dari 35 sampai 45 = " + jumlah(35,
45));
}
|
Baris 1-7 mendefinisikan metode
yang bernama jumlah dengan dua
parameter i dan j. Statemen-statemen di dalam metode main memanggil jumlah(1, 10) untuk menghitung
penjumlahan dari 1 sampai 10, jumlah(20,
30) untuk menghitung penjumlahan dari 20 sampai 30, jumlah(35, 45) untuk menghitung penjumlahan dari 35 sampai 45.
Suatu metode merupakan koleksi
statemen-statemen yang dikelompokkan bersama untuk melakukan suatu operasi.
Dalam beberapa bab sebelumnya, Anda telah menggunakan beberapa metode yang
terdefinisi di dalam pustaka JAVA seperti
System.out.println, JOption-Pane.showMessageDialog,
JOptionPane.showInputDialog,
Integer.parseInt, Double.parseDouble,
System.exit, Math.pow,
dan Math.random. Pada bab ini, Anda akan belajar bagaimana
mendefinisikan metode Anda sendiri dan menerapkan abstraksi metode untuk
menyelesaikan masalah-masalah yang lebih kompleks.
5.2 Mendefinisikan Suatu Metode
Sintaks untuk mendefinisikan suatu
metode adalah sebagai berikut:
pemodifikasi
tipeNilaiBalik namaMetode(daftar parameter) {
// Tubuh metode;
}
Sekarang mari kita periksa suatu
metode yang diciptakan untuk mencari integer
yang lebih besar dari dua integer. Metode ini, diberi nama max, memiliki dua parameter, num1 dan num2. Salah satu dari kedua integer tersebut dijadikan nilai balik
fungsi. Gambar 5.1 mengilustrasikan komponen-komponen metode ini.
Gambar
5.1
Suatu definisi metode yang memuat header metode dan tubuh metode
Header metode memuat pemodifikasi
(modifier), tipe nilai balik, nama
metode, dan parameter-parameter formal. Pemodifikasi statik digunakan pada
semua metode dalam bab ini. Alasan penggunaannya akan dijelaskan pada Bab. 8.
Suatu
metode boleh memiliki nilai balik. tipeNilaiBalik
adalah tipe data nilai yang dikembalikan oleh suatu metode. Beberapa metode
melakukan operasi tanpa perlu memberikan nilai balik. Pada
kasus ini, tipeNilaiBalik adalah
katakunci void. Sebagai contoh, tipeNilaiBalik adalah void dalam metode main, sama seperti System.exit,
System.out.println, dan JOptionPane.showMessageDialog.
Jika suatu metode mengembalikan suatu nilai, maka disebut dengan metode pengembali-nilai, sebaliknya
disebut dengan metode void.
Variabel-variabel yang
didefinisikan dalam header metode dikenal dengan parameter formal atau parameter
saja. Ketika suatu metode dipanggil, Anda melewatkan suatu nilai kepada
parameter. Parameter ini dikenal dengan parameter
aktual. Daftar parameter merujuk
pada tipe, urutan, dan jumlah parameter dalam suatu metode. Nama metode dan
daftar parameter membentuk sidik metode
atau tanda-tangan metode. Parameter
bersifat opsional; artinya suatu metode bisa saja tidak memiliki satu parameter
pun. Sebagai contoh, metode Math.random()
tidak memiliki parameter.
Tubuh metode memuat koleksi
statemen yang mendefinisikan apa yang dilakukan suatu metode. Tubuh metode dari
metode max menggunakan suatu
statemen if untuk menentukan angka
mana yang lebih besar dan menjadikan nilai angka tersebut sebagai nilai balik.
Agar suatu metode pengembali-nilai dapat memberikan suatu nilai balik,
digunakan katakunci return pada
nilai balik tersebut. Metode berhenti setelah mengeksekusi statemen return.
Dalam beberapa bahasa pemrograman, metode disebut
juga dengan fungsi atau prosedur. Suatu metode pengembali-nilai disebut
dengan fungsi; suatu metode void disebut dengan prosedur.
Dalam header metode, Anda perlu mendeklarasikan tipe
data setiap parameter secara terpisah. Misalnya, max(int num1, int num2), tetapi max(int
num1, num2) adalah
salah.
Perbedaan antara “mendefinisikan metode” dengan
“mendeklarasikan variabel”. Suatu definisi mendefinisikan item-item yang
terdefinisi, tetapi suatu deklarasi biasanya hanya mengalokasikan memori
untuk menyimpan data untuk item yang terdeklarasi.
|
5.3 Memanggil Suatu Metode
Dalam menciptakan suatu metode,
Anda mendefinisikan apa yang dilakukan oleh metode tersebut. Untuk menggunakan
suatu metode, Anda harus memanggilnya. Ada dua cara memanggil metode,
tergantung apakah metode tersebut memiliki nilai balik atau tidak.
Jika metode memberikan suatu nilai
balik, maka pemanggilan terhadap metode itu diperlakukan seperti layaknya suatu
nilai. Sebagai contoh,
int lebihBesar = max(3, 4);
memanggil metode max(3, 4) dan menugaskan hasil metode
itu kepada lebihBesar. Contoh lain yang
memperlakukan pemanggilan metode sebagai nilai adalah
System.out.println(max(3,
4));
yang menampilkan nilai balik dari
pemanggilan metode max(3, 4).
Jika metode mengembalikan void, maka pemanggilan terhadap metode
tersebut harus berupa suatu statemen. Sebagai contoh, metode println memberikan
nilai balik void. Pemanggilan
berikut ini adalah suatu statemen:
System.out.println("JAVA
itu Tangguh!");
Ketika suatu program memanggil
suatu metode, kendali program dipindahkan kepada metode yang dipanggil
tersebut. Metode yang dipanggil mengembalikan kendali kepada pemanggil setelah
statemen return dieksekusi atau
ketika kurung kurawal penutup suatu metode diraih. Kode5.1 menampilkan suatu
program utuh yang digunakan untuk menguji metode max.
Kode5.1 UjiMax.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public class UjiMax {
/** metode utama */
public
static void main(String[] args) {
int
i = 5;
int
j = 2;
int
k = max(i, j);
System.out.println("Nilai maksimum antara " + i +
"
dan " + j + " adalah
" + k);
}
/** Mengembalikan nilai maksimum antara dua
angka */
public static int max(int num1, int num2) {
int
hasil;
if
(num1 > num2)
hasil = num1;
else
hasil = num2;
return hasil;
}
}
|
Keluaran:
Nilai
maksimum antara 5 dan 2 adalah 5
Program memuat metode main
dan metode max. Metode main sama seperti metode lain, kecuali
bahwa metode tersebut dipanggil oleh JVM.
Header metode main
selalu sama. Seperti contoh ini, header metode main memuat pemodifikasi public
dan static, memberikan nilai balik void, nama metode main, dan suatu parameter tipe String[].
String[] mengindikasikan bahwa
parameter merupakan suatu array String,
yang akan dibahas pada Bab. 6.
Statemen-statemen di dalam main
bisa saja memanggil metode-metode lain yang didefinisikan di dalam kelas yang
memuat metode main atau di dalam
kelas-kelas lain. Pada contoh ini, metode main
memanggil max(i, j), yang
didefinisikan di dalam kelas yang sama dengan metode main.
Ketika metode main
dipanggil (baris 6), nilai variabel i
sebesar 5 dilewatkan kepada num1,
dan nilai variabel j sebesar 2
dilewatkan kepada num2 di dalam
metode max. Aliran kendali program
beralih ke metode max. Kemudian
metode max dieksekusi. Ketika
statemen return dalam metode max dieksekusi, kendali program
dikembalikan kepada pemanggilnya (dalam kasus ini, pemanggil adalah metode main). Proses ini diilustrasikan pada
Gambar 5.2.
Gambar 5.2 Ketika metode max
dipanggil, aliran kendali program beralih kepada metode tersebut. Begitu metode
max selesai dieksekusi, kendali
program kembali kepada pemanggil
Suatu
statemen return dibutuhkan oleh metode pengembali-nilai.
Metode yang ditampilkan pada (a) di bawah ini secara legal benar, tetapi
memiliki error kompilasi karena kompiler JAVA berpikir bahwa sangat mungkin
metode ini tidak mengembalikan nilai balik.
Untuk
mengatasi masalah ini, hapuskan if( n < 0)
pada (a), sehingga kompiler melihat statemen return untuk dieksekusi apapun hasil evaluasi
terhadap statemen if.
Metode
memampukan pendaur-ulangan dan pemakaian secara bersama. Metode max
bisa saja dipanggil dari sembarang kelas selain kelas UjiMax.
Jika Anda menciptakan kelas lain, Anda bisa memanggil metode max
menggunakan NamaKelas.namaMetode
(misalnya, UjiMax.max).
|
5.3.1 Tumpukan Pemanggilan
Setiap kali suatu metode dipanggil, sistem menyimpan parameter
dan variabel di suatu memori yang dikenal dengan tumpukan, yang menyimpan
elemen-elemen secara LIFO (last-in, first-out). Ketika suatu metode memanggil
metode lain, ruang memori dalam tumpukan untuk pemanggil dibiarkan utuh, dan
ruang memori baru diciptakan untuk menangani pemanggilan metode. Ketika metode
yang dipanggil selesai dieksekusi dan kendali program kembali kepada
pemanggilnya, maka ruang memori yang tercipta untuk metode yang dipanggil
dihapus.
Memahami tumpukan pemanggilan dapat membantu Anda mengerti
bagaimana metode-metode dipanggil. Variabel-variabel yang didefinisikan di
dalam metode main adalah i, j,
dan k. Variabel-variabel yang
didefinisikan dalam metode max
adalah num1 dan num2. Variabel num1 dan num2 didefinisikan dalam sidik metode
dan merupakan parameter metode. Gambar 5.3 mengilustrasikan variabel-variabel
di dalam tumpukan.
Gambar 5.3 Ketika metode max
dipanggil, aliran kendali program beralih ke metode max. Setelah metode max
selesai dieksekusi, kendali program kembali kepada pemanggil.
5.4 Contoh Metode void
Contoh sebelumnya adalah metode pengembali-nilai. Pada bagian
ini, ditunjukkan untuk mendefinisikan dan memanggil suatu metode main. Kode5.2 memberikan suatu program
yang mendefinisikan suatu metode bernama cetakNilai
dan memanggilnya untuk menampilkan nilai untuk skor yang diberikan.
Kode5.2 UjiMetodeVoid.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public class UjiMetodeVoid {
public static void main(String[] args) {
System.out.print("Nilai adalah ");
cetakNilai(78.5);
System.out.print("Nilai
adalah ");
cetakNilai(59.5);
}
public static void cetakNilai(double skor) {
if (skor >= 90.0)
{
System.out.println('A');
}
else
if (skor >= 80.0) {
System.out.println('B');
}
else
if (skor >= 70.0) {
System.out.println('C');
}
else
if (skor >= 60.0) {
System.out.println('D');
}
else
{
System.out.println('F');
}
}
}
|
Keluaran:
Nilai adalah
C
Nilai adalah
F
Metode cetakNilai
merupakan suatu metode void, yang
tidak mengembalikan nilai apapun. Pemanggilan terhadap suatu metode void harus berupa statemen. Jadi,
metode cetakNilai dipanggil sebagai
suatu statemen pada baris 4 dalam metode main.
Sama seperti statemen dalam JAVA, harus diakhiri dengan tanda titik koma.
Untuk melihat perbedaan antara metode pengembali-nilai dengan
metode void, maka kode5.2 akan
didesain-ulang menggunakan metode pengembali-nilai. Metode yang baru,
dapatNilai, mengembalikan nilai seperti ditunjukkan pada kode5.3.
Kode5.3 UjiMetodePengembaliNilai.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class UjiMetodePengembaliNilai {
public
static void main(String[] args) {
System.out.print("Nilai adalah " + dapatNilai(78.5));
System.out.print("\nNilai adalah "+ dapatNilai(59.5));
}
public static char dapatNilai(double skor) {
if
(skor >= 90.0)
return 'A';
else
if (skor >= 80.0)
return 'B';
else
if (skor >= 70.0)
return 'C';
else
if (skor >= 60.0)
return 'D';
else
return 'F';
}
}
|
Keluaran:
Nilai adalah
C
Nilai adalah
F
Metode dapatNilai
yang didefinisikan pada baris 7-18 memberikan nilai balik berupa suatu karakter
nilai berdasarkan nilai skor numerik.
Suatu
statemen return tidak dibutuhkan oleh metode void,
tetapi bisa digunakan untuk menghentikan metode dan mengalihkan kendali program
kepada pemanggil. Sintaksnya cuku sederhana:
return;
Hal
ini tidak sering dilakukan, tetapi kadang-kadang dibutuhkan untuk memaksa
kendali program di dalam suatu metode void. Sebagai contoh, kode berikut ini
memiliki suatu statemen return untuk menghentikan metode ketika skor tidak
valid.
public
static void cetakNilai(double
skor) {
if (skor < 0 || skor > 100) {
System.out.println("Skor tidak
valid");
return;
}
if (skor >= 90.0) {
System.out.println('A');
}
else if (skor >= 80.0) {
System.out.println('B');
}
else if (skor >= 70.0) {
System.out.println('C');
}
else if (skor >= 60.0) {
System.out.println('D');
}
else
{
System.out.println('F');
}
}
|
5.5 Melewatkan Parameter Dengan
Nilai
Kekuatan suatu metode adalah kemampuannya dalam bekerja dengan
parameter. Anda bisa menggunakan println
untuk menampilkan sembarang string dan metode max untuk mencari nilai maksimum di antara dua integer. Ketika
memanggil suatu metode, Anda perlu menyediakan argumen, yang harus diberikan
dalam urutan yang sama dengan parameter pada sidik metode. Hal ini dikenal
dengan asosiasi urutan parameter.
Sebagai contoh, metode ini menampilkan suatu pesan sebanyak n kali:
public
static void nPrintln(String
pesan, int n) {
for (int i = 0; i < n; i++)
System.out.println(pesan);
}
Anda dapat menggunakan nPrintln(“JAVA”,
3) akan menampilkan “JAVA”
sebanyak tiga kali. Statemen nPrintln(“JAVA”,
3) melewatkan parameter string
aktual “JAVA” kepada parameter pesan; melewatkan 3 kepada n; dan mencetak “JAVA” tiga kali. Namun, statemen nPrintln(3, “JAVA”) akan salah. Tipe data 3 tidak cocok dengan
parameter pertama, pesan, begitu
juga dengan parameter kedua, “JAVA”,
tidak sesuai dengan parameter n.
Ketika Anda memanggil suatu metode dengan parameter, nilai
argumen dilewatkan kepada parameter. Hal ini disebut dengan pelewatan dengan nilai. Jika argumen
adalah suatu variabel, bukan nilai literal, maka nilai variabel tersebut
dilewatkan kepada parameter. Nilai variabel tidak terpengaruh oleh perubahan
yang terjadi pada parameter di dalam metode. Seperti pada kode5.4, nilai x(1) dilewatkan kepada parameter n untuk memanggil metode inkremen (baris 5). Nilai n diinkremen sebesar 1 di dalam metode
(baris 10), tetapi x tetap tidak
berubah.
Kode5.4 Inkremen.java
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class Inkremen {
public
static void main(String[] args) {
int
x = 1;
System.out.println("Sebelum pemanggilan, x adalah "
+ x);
inkremen(x);
System.out.println("Setelah pemanggilan, x adalah "
+ x);
}
public
static void inkremen(int n) {
n++;
System.out.println("n di dalam metode adalah " + n);
}
}
|
Keluaran:
Sebelum
pemanggilan, x adalah 1
n di dalam
metode adalah 2
Setelah
pemanggilan, x adalah 1
Kode5.5 memberikan suatu program lain yang mendemonstrasikan
pengaruh pelewatan dengan nilai. Program menciptakan suatu metode untuk menukar
dua variabel. metode tukar dipanggil dengan pelewatan dua variabel. Yang
menarik adalah bahwa nilai-nilai argumen tidak berubah setelah metode
dipanggil.
Kode5.5 UjiPelewatanDenganNilai.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public class UjiPelewatanDenganNilai {
/** Metode utama */
public
static void main(String[] args) {
// Mendeklarasikan dan menginisialisasi
variabel
int
num1 = 1;
int
num2 = 2;
System.out.println("Sebelum memanggil metode tukar, num1 adalah " +
num1 + " dan num2 adalah " + num2);
// Memanggil metode tukar untuk menukar
dua variabel
tukar(num1, num2);
System.out.println("Setelah memanggil metode tukar, num1
adalah " +
num1 + " dan num2 adalah " + num2);
}
/** Menukar dua variabel */
public static void tukar(int n1, int n2) {
System.out.println("\tDi dalam metode
tukar");
System.out.println("\t\tSebelum penukaran n1 adalah "
+ n1
+ " n2 adalah " + n2);
// Menukar n1 dengan n2
int
temp = n1;
n1 = n2;
n2 = temp;
System.out.println("\t\tSetelah penukaran n1 adalah "
+ n1
+ " n2 adalah " + n2);
}
}
|
Keluaran:
Sebelum
memanggil metode tukar, num1 adalah 1 dan num2 adalah 2
Di dalam metode tukar
Sebelum penukaran n1 adalah 1 n2 adalah
2
Setelah penukaran n1 adalah 2 n2 adalah
1
Setelah
memanggil metode tukar, num1 adalah 1 dan num2 adalah 2
Sebelum metode tukar
dipanggil (baris 12), num1 adalah 1
dan num2 adalah 2. Setelah metode tukar dipanggil, num1 masih 1 dan num2
masih 2. Kedua nilai tidak saling ditukar. Seperti ditunjukkan pada Gambar 5.4,
nilai-nilai argumen num1 dan num2 dilewatkan kepada n1 dan n2, tetapi n1 dan n2 memiliki lokasi memori yang berbeda
dari num1 dan num2. Oleh karena itu, perubahan pada n1 dan n2 tidak
berpengaruh pada num1 dan num2.
Gambar 5.4 Nilai-nilai variabel dilewatkan kepada parameter-parameter
metode
5.6 Kode Modular
Metode bisa digunakan untuk mereduksi kode yang berlebihan dan
memampukan pendaur-ulangan kode. Metode juga dapat dipakai untuk memodularkan
dan memperbaiki kualitas suatu program.
Kode4.8 memberikan suatu program yang meminta pengguna untuk
memasukkan dua integer dan menampilkan GCD atas kedua integer tersebut. Anda
bisa menulis-ulang program tersebut menggunakan suatu metode, seperti
ditunjukkan pada Gambar 5.6 sebagai berikut:
Kode5.6 MetodeGCD.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
import java.util.Scanner;
public class MetodeGCD {
/** Metode utama */
public
static void main(String[] args) {
// Menciptakan Scanner
Scanner masukan = new Scanner(System.in);
// Meminta pengguna memasukkan dua integer
System.out.print("Masukkan integer pertama: ");
int
n1 = masukan.nextInt();
System.out.print("Masukkan integer kedua: ");
int
n2 = masukan.nextInt();
System.out.println("GCD atas " + n1 +
" dan " + n2 + " adalah " + gcd(n1, n2));
}
/** Memberikan nilai balik gcd atas dua
integer */
public static int gcd(int n1, int n2) {
int gcd = 1; // gcd awal
= 1
int
k = 2; // gcd yang mungkin
while
(k <= n1 && k <= n2) {
if (n1 % k == 0 && n2 % k == 0)
gcd = k; // Perbarui gcd
k++;
}
return gcd; // Memberikan nilai balik gcd
}
}
|
Keluaran:
Masukkan
integer pertama: 15
Masukkan
integer kedua: 355
GCD atas 15
dan 355 adalah 5
Dengan mengenkapsulasi kode untuk mendapatkan gcd dalam suatu
metode, program ini memiliki beberapa keuntungan:
- Program mengisolasi masalah untuk menghitung gcd dari bagian kode lain dalam metode main. Jadi, logika programmer menjadi lebih terang dan program mudah dibaca.
- Error dalam menghitung gcd dilokalisir di dalam metode gcd, yang mempersempit skop pembetulan error (debugging).
- Metode gcd sekarang bisa digunakan oleh program lain.
Kode5.7 menerapkan konsep modularisasi kode untuk memperbaiki
kode4.14, AngkaPrima.java.
Kode5.7 MetodeAngkaPrima.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
public class MetodeAngkaPrima {
public
static void main(String[] args) {
System.out.println("50 angka prima pertama adalah \n");
cetakAngkaPrima(50);
}
public
static void cetakAngkaPrima(int
angkaPrima) {
final
int JUMLAH_ANGKA_PRIMA_PER_BARIS = 10; // 10 per baris
int
hitung = 0; // Menghitung jumlah
angka prima
int
angka = 2; // Angka yang akan diuji
keprimaannya
// Secara berulang menemukan angka-angka
prima
while
(hitung < angkaPrima) {
// Menampilkan angka prima dan menambah
hitung
if(
apaPrima(angka)) {
hitung++; // Menambah hitung
if (hitung %
JUMLAH_ANGKA_PRIMA_PER_BARIS == 0) {
//Menampilkan angka prima dan
mengganti baris
System.out.printf("%-5s\n",
angka);
}
else
System.out.printf("%-5s",
angka);
}
// Memeriksa apakah angka berikutnya
adalah prima
angka++;
}
}
/** Memeriksa apakah suatu angka prima atau
tidak */
public static boolean apaPrima(int angka) {
for
(int pembagi = 2; pembagi <=
angka / 2; pembagi++) {
if
(angka % pembagi == 0) { // Jika true,
angka bukan prima
return false; // angka bukan prima
}
}
return true; // angka prima
}
}
|
Keluaran:
50 angka
prima pertama adalah
2 3
5 7 11
13 17 19
23 29
31 37
41 43 47
53 59 61
67 71
73 79
83 89 97
101 103 107
109 113
127 131
137 139 149
151 157 163
167 173
179 181
191 193 197
199 211 223
227 229
5.7 Mengkonversi Desimal Menjadi
Heksadesimal
Heksadesimal seringkali digunakan dalam pemrograman. Tantangannya
di sini adalah menyajikan suatu program yang bisa mengubah desimal menjadi
heksadesimal.
Untuk mengkonversi suatu angka desimal
menjadi suatu angka desimal dilakukan
pencarian dijit-dijit heksadesimal
, dan
sehingga
Angka-angka ini dapat ditemukan dengan secara terus-menerus
membagi
dengan 16 sampai hasil bagi (quotient) 0.
Sisa-sisa adalah
, dan
.
Sebagai contoh, angka desimal 123 adalah 7B dalam heksadesimal.
Konversi ini dilakukan sebagai berikut:
Program pada kode5.8 meminta pengguna untuk memasukkan suatu
angka desimal dan mengkonversinya menjadi bilangan heksadesimal dalam string.
Kode5.8 KonversiDesimal2Hex.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
import java.util.Scanner;
public class KonversiDesimal2Hex {
/** Metode utama */
public
static void main(String[] args) {
// Menciptakan Scanner
Scanner masukan = new Scanner(System.in);
// Meminta pengguna
memasukkan suatu angka desimal
System.out.print("Masukkan suatu angka desimal:
");
int
desimal = masukan.nextInt();
System.out.println("Angka desimal untuk angka desimal
" +
desimal + " adalah " + desimalKeHex(desimal) );
}
/** Mengkonversi desimal menjadi
heksadesimal sebagai suatu string */
public static String desimalKeHex(int desimal)
{
String hex = "";
while
(desimal != 0) {
int
nilaiHex = desimal % 16;
hex =keHexChar(nilaiHex) + hex;
desimal = desimal / 16;
}
return
hex;
}
/** Mengkonversi integer menjadi satu dijit
hex dalam karakter */
public static char keHexChar(int nilaiHex) {
if
(nilaiHex <= 9 && nilaiHex >= 0)
return
(char)(nilaiHex + '0');
else
// nilaiHex <= 15 && nilaiHex >= 10
return
(char)(nilaiHex - 10 + 'A');
}
}
|
Keluaran:
Masukkan
suatu angka desimal: 823242
Angka
desimal untuk angka desimal 823242 adalah C8FCA
Masukkan
suatu angka desimal: 3456
Angka
desimal untuk angka desimal 3456 adalah D80
Program menggunakan metode desimalKeHex
(baris 18-28) untuk mengkonversi suatu integer desimal menjadi angka
heksadesimal dalam string. Metode ini mendapatkan sisa pembagian atas integer
desimal oleh 16 (baris 22). Sisa yang didapatkan dikonversi menjadi karakter
dengan memanggil metode keHexChar
(baris 23). Karakter yang didapatkan kemudian digabungkan ke string
heksadesimal (baris 23). String heksadesimal pada mulanya kosong (baris 19).
Metode keHexChar
(baris 31-36) mengkonversi suatu nilaiHex
antara 0 sampai 15 menjadi suatu karakter heksadesimal. Jika nilaiHex memiliki rentang 0 sampai 9,
maka akan dikonversi menjadi (char)(hexValue + '0') (baris 33). Ingat bahwa bila menambahkan suatu
karakter dengan suatu integer, maka Unicode atas karakter tersebut digunakan
dalam evaluasi. Sebagai contoh, jika diberikan nilaiHex adalah 5, (char)(hexValue
+ '0') akan memberikan nilai balik sebesar 5. Dengan logika yang sama, jika
nilaiHex dalam rentang 10 sampai 15, maka akan dikonversi menjadi (char)(hexValue
+ 'A') (baris 35). Sebagai contoh, jika diberikan nilaiHex adalah
11, (char)(hexValue + 'A') akan memberikan nilai balik sebesar ‘B’.
5.8 Overloading Metode
Metode max yang telah
diciptakan sebelumnya hanya bisa bekerja dengan tipe data int saja. Tetapi bagaimana jika Anda ingin menentukan mana yang
tertinggi dari dua angka pecahan? Solusinya adalah menciptakan metode lain
dengan nama sama namun dengan parameter-parameter yang berbeda, seperti
ditunjukkan pada kode berikut ini:
public
static double max(double
num1, double num2) {
if (num1 > num2)
return num1;
else
return num2;
}
Jika Anda memanggil metode max
dengan parameter-parameter int, maka
metode max dengan dafta parameter int
yang dipanggil, Jika Anda memanggil metode max
dengan parameter-parameter double,
maka metode max dengan dafta parameter double
yang dipanggil. Hal ini disebut dengan overloading
metode; yaitu bahwa, dua metode dengan nama sama tetapi dengan daftar
perameter yang berbeda di dalam satu kelas. Kompiler JAVA yang menentukan
metode mana yang digunakan berdasarkan pada sidik metode.
Kode5.9 adalah suatu program untuk menciptakan tiga metode. Yang
pertama adalah metode untuk mencari nilai maksimum int, yang kedua adalah metode untuk mencari nilai maksimum double, dan yang ketiga adalah metode
untuk mencari nilai maksimum double di
antara tiga nilai double.
Kode5.9 UjiOverloadingMetode.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
public class UjiOverloadingMetode {
/** Metode utama */
public
static void main(String[] args) {
// Memanggil metode max dengan
parameter-parameter int
System.out.println("Nilai maksimum antara 3 dan 4 adalah "
+ max(3, 4));
// Memanggil metode max dengan
parameter-parameter double
System.out.println("Nilai maksimum antara 3.0 dan 5.4 adalah
"
+ max(3.0, 5.4));
// Memanggil metode max dengan tiga
parameter double
System.out.println("Nilai maksimum antara 3.0,
5.4, dan 10.14 adalah "
+ max(3.0, 5.4, 10.14));
}
/** Memberikan nilai balik berupa nilai
maksium antara dua int */
public static int max(int num1, int num2){
if
(num1 > num2)
return
num1;
else
return
num2;
}
/** Memberikan nilai balik berupa nilai
maksium antara dua double */
public static double max(double num1, double num2){
if
(num1 > num2)
return
num1;
else
return
num2;
}
/** Memberikan nilai balik berupa nilai
maksium antara tiga double */
public static double max(double num1, double num2,
double num3){
return
max(max(num1, num2), num3);
}
}
|
Keluaran:
Nilai
maksimum antara 3 dan 4 adalah 4
Nilai
maksimum antara 3.0 dan 5.4 adalah 5.4
Nilai
maksimum antara 3.0, 5.4, dan 10.14 adalah 10.14
Ketika memanggil metode max(3,
4) (baris 6), metode max untuk
mencari nilai maksimum dari dua int
yang dipanggil. Ketika memanggil metode max(3.0,
5.4) (baris 10), metode max
untuk mencari nilai maksimum dari dua double
yang dipanggil. Ketika memanggil metode max(3.0,
5.4, 10.14) (baris 14), metode max
untuk mencari nilai maksimum dari tiga double
yang dipanggil.
Dapatkah Anda memanggil metode max dengan suatu nilai int
dan suatu nilai double, seperti max(2, 2.5)? Metode max manakah yang dipanggil? Jawabannya
adalah bisa. Metode max untuk
mencari nilai maksimum dari dua double
yang dipanggil. Nilai argumen 2 secara otomatis dikonversi menjadi suatu nilai double dan dilewatkan kepada metode
ini.
Anda mungkin bertanya-tanya mengapa bukan max(double, double) yang dipanggil saat pemanggilan max(3, 4). Kedua max(int, int) dan max(double,
double) adalah kecocokan yang mungkin untuk max(3, 4). Kompiler JAVA menerapkan kriteria yang spesifik dalam
pemanggilan suatu metode. Karena metode max(int,
int) merupakan kriteria yang paling spesifik daripada max(double, double), maka max(int,
int) yang digunakan untuk memanggil max(3,
4).
Perhatikan
bahwa metode-metode yang dioverload harus memiliki daftar parameter yang
berbeda. Anda tidak bisa mengoverload metode berdasarkan pada tipe nilai
balik atau pemodifikasi.
Kadang-kala
terdapat dua atau lebih kecocokan yang mungkin dalam pemanggilan suatu
metode, dan kompiler JAVA tidak bisa menemukan salah satu yang paling
spesifik. Hal ini dikenal dengan pemanggilan ambigu. Pemanggilan ambigu
menyebabkan error kompilasi. Perhatikan kode berikut ini:
public
class OverloadingAmbigu
{
public static void main(String[] args) {
System.out.println(max(1, 2));
}
public static double max(int num1, double num2) {
if (num1 > num2)
return num1;
else
return num2;
}
public static double max(double
num1, int num2){
if (num1 > num2)
return num1;
else
return num2;
}
}
Kedua
max(int, double) dan max(double, int)
merupakan kandidat yang mungkin untuk max(1, 2). Karena tidak satupun lebih spesifik
dari yang lain, maka hal ini menciptkan pemanggilan ambigu dan menyebabkan
error kompilasi.
|
5.9 Skop Variabel
Skop suatu variabel adalah bagian dari program dimana variabel
dapat direferensi. Suatu variabel yang didefinisikan di dalam suatu metode
dikenal dengan variabel lokal.
Gambar 5.5 Suatu variabel yang dideklarasikan dalam bagian aksi-awal suatu loop for memiliki skop di dalam keseluruhan
loop.
Skop dari suatu variabel lokal dimulai dari pendeklarasian
variabel tersebut dan berlanjut ke akhir blok yang memuat variabel itu. Suatu
variabel lokal harus dideklarasikan dan ditugasi nilai sebelum digunakan.
Suatu variabel yang dideklarasikan dalam bagian aksi-awal suatu loop for memiliki skop di dalam keseluruhan
loop. Tetapi suatu variabel yang dideklarasikan di dalam tubuh loop memiliki
skop dimulai dari pendeklarasian variabel tersebut dan berlanjut ke akhir blok
yang memuat variabel itu, seperti yang ditampilkan pada Gambar 5.5.
Anda bisa mendeklarasikan suatu variabel lokal dengan nama sama
di dalam blok-blok yang berbeda di dalam suatu metode, tetapi Anda tidak bisa
mendeklarasikan suatu variabel lokal dua kali di dalam blok yang sama atau di
dalam blok-blok nested, seperti pada Gambar 5.6.
Gambar 5.6 Suatu variabel lokal dapat dideklarasikan berkali-kali dalam
blok-blok yang tidak nested, tetapi
tidak hanya boleh dideklarasikan sekali saja dalam blok-blok nested
Jangan
deklarasikan suatu variabel di dalam suatu blok dan kemudian mencoba
menggunakannya di luar blok tersebut. Berikut adalah salah satu contoh yang
kerap kali terjadi:
for
(int i
= 0; i < 10; i++) {
}
System.out.println(i);
Statemen
terakhir akan menyebabkan suatu error sintaks, karena variabel i
tidak terdefinisi di luar loop for.
|
5.10 Kelas Math
Kelas Math memuat
metode-metode yang dibutuhkan untuk melakukan fungsi-fungsi matematik dasar.
Anda telah menggunakan metode pow(a, b)
untuk menghitung
pada kode2.8, HitungHutang.java dan metode Math.random() untuk pada kode3.4,
KuisPengurangan.java. Bagian ini akan mengenalkan Anda tentang metode-metode
lain dalam kelas Math. Metode-metode
tersebut dikategorikan sebagai metode trigonometrik, metode eksponen, dan
metode servis. Di samping metode-metode, kelas Math juga menyediakan dua konstanta double, PI dan E (logaritma natural). Anda bisa
menggunakan dua konstanta ini sebagai Math.PI
dan Math.E dalam sembarang program.
5.10.1 Metode-Metode Trogonometrik
Kelas Math memuat
metode-metode trigonometrik sebagai berikut:
/**
Mengembalikan sinus trigonometrik atas suatu sudut dalam radian */
public
static double sin(double
radian)
/**
Mengembalikan kosinus trigonometrik atas suatu sudut dalam radian */
public
static double cos(double
radian)
/**
Mengembalikan tangent trigonometrik atas suatu sudut dalam radian */
public
static double tan(double
radian)
/**
Mengubah sudut dalam derajat menjadi radian */
public
static double toRadians(double
derajat)
/**
Mengubah sudut dalam radian menjadi derajat */
public
static double toDegrees(double
radian)
/**
Mengembalikan sudut dalam radian untuk invers dari sin */
public
static double asin(double
a)
/**
Mengembalikan sudut dalam radian untuk invers dari cos */
public
static double acos(double
a)
/**
Mengembalikan sudut dalam radian untuk invers dari tan */
public
static double atan(double a)
Parameter untuk sin, cos, dan tan adalah sudut dalam radian. Nilai balik untuk asin, acos, dan
atan adalah derajat dalam radian dengan rentang
sampai
. Satu
derajat sama dengan
dalam radian, 90 derajat sama dengan
, dan
30 derajat sama dengan
dalam radian.
Sebagai contoh,
Math.toDegrees(Math.PI
/ 2) menghasilkan 90.0
Math.toRadians(30)
menghasilkan π/6
Math.sin(0)
menghasilkan 0.0
Math.sin(Math.toRadians(270))
menghasilkan -1.0
Math.sin(Math.PI
/ 6) menghasilkan 0.5
Math.sin(Math.PI
/ 2) menghasilkan 1.0
Math.cos(0)
menghasilkan 1.0
Math.cos(Math.PI
/ 6) menghasilkan 0.866
Math.cos(Math.PI
/ 2) menghasilkan 0
Math.asin(0.5)
menghasilkan π/6
5.10.2 Metode-Metode Eksponen
Ada lima metode yang berkaitan dengan eksponen dalam kelas Math:
/**
Mengembalikan
*/
public
static double exp(double
x)
/**
Mengembalikan ln(x) =
(x)
*/
public
static double log(double
x)
/**
Mengembalikan
(x)
*/
public
static double log10(double
x)
/**
Mengembalikan
*/
public
static double pow(double
a, double b)
/**
Mengembalikan
untuk x >= 0 */
public
static double sqrt(double x)
Sebagai contoh,
Math.exp(1)
mengembalikan 2.71828
Math.log(Math.E)
mengembalikan 1.0
Math.log10(10)
mengembalikan 1.0
Math.pow(2,
3) mengembalikan 8.0
Math.pow(3,
2) mengembalikan 9.0
Math.pow(3.5,
2.5) mengembalikan 22.91765
Math.sqrt(4)
mengembalikan 2.0
Math.sqrt(10.5)
mengembalikan 3.24
5.10.3 Metode-Metode Pembulatan
Kelas Math memuat
lima metode pembulatan:
/**
x dibulatkan ke atas ke integer terdekat. Integer ini dikembalikan
* sebagai suatu nilai double. */
public
static double ceil(double
x)
/**
x dibulatkan ke bawah ke integer terdekat. Integer ini dikembalikan
* sebagai suatu nilai double. */
public
static double floor(double
x)
/**
x dibulatkan ke integer terdekat. Jika x sama-sama dekat kepada
* dua integer, maka dibulatkan kepada integer
yang genap sebagai
* suatu nilai double. */
public
static double rint(double
x)
/**
Mengembalikan (int)Math.floor(x + 0.5). */
public
static int round(float
x)
/**
Mengembalikan (long)Math.floor(x + 0.5). */
public
static long round(double x)
Sebagai contoh,
Math.ceil(2.1)
mengembalikan 3.0
Math.ceil(2.0)
mengembalikan 2.0
Math.ceil(-2.0)
mengembalikan –2.0
Math.ceil(-2.1)
mengembalikan -2.0
Math.floor(2.1)
mengembalikan 2.0
Math.floor(2.0)
mengembalikan 2.0
Math.floor(-2.0)
mengembalikan –2.0
Math.floor(-2.1)
mengembalikan -3.0
Math.rint(2.1)
mengembalikan 2.0
Math.rint(-2.0)
mengembalikan –2.0
Math.rint(-2.1)
mengembalikan -2.0
Math.rint(2.5)
mengembalikan 2.0
Math.rint(3.5)
mengembalikan 4.0
Math.rint(-2.5)
mengembalikan -2.0
Math.round(2.6f)
mengembalikan 3 // Mengembalikan int
Math.round(2.0)
mengembalikan 2 // Mengembalikan long
Math.round(-2.0f)
mengembalikan -2
Math.round(-2.6)
mengembalikan -3
5.10.4 Metode max, min, dan abs
Metode max dan min dioverload sehingga memberikan nilai balik
berupa angka maksimum dan minimum dari dua angka (int, long, float, atau double). Sebgai contoh, max(3.4,
5.0) menghasilkan 5.0 , dan min(3,
2) menghasilkan 2.
Metode abs dioverload sehingga memberikan nilai balik berupa
nilai absolut atas suatu angka (int,
long, float, atau double).
Sebagai, contoh
Math.max(2,
3) mengembalikan 3
Math.max(2.5,
3) mengembalikan 3.0
Math.min(2.5,
3.6) mengembalikan 2.5
Math.abs(-2)
mengembalikan 2
Math.abs(-2.1)
mengembalikan 2.1
5.10.5 Metode random
Anda telah menggunakan metode random() untuk membangkitkan suatu nilai double acak dengan rentang
lebih besar atau sama dengan 0 dan lebih rendah dari 1 (0 <=Math.random() < 1.0). Metode ini sangat berguna. Anda
dapat menggunakannya untuk menuliskan suatu ekspresi sederhana untuk
membangkitkan angka-angka acak dengan sembarang rentang. Sebagai contoh,
(int)
(Math.random() * 10) = untuk
membangkitkan suatu angka acak 0
sampai 9.
50 + (int)
(Math.random() * 50) = untuk
membangkitkan suatu angka acak 50
sampai 99.
Pada umumnya,
a + (int)
(Math.random() * b) = untuk
membangkitkan suatu angka acak a
sampai a + b.
Anda
bisa membaca dokumentasi yang informatif untuk kelas Math secara online di http://java.sun.com/ javase/6/docs/api/index.html, seperti
tertampil pada Gambar 5.7.
Gambar 5.7 Anda bisa membaca dokumentasi JAVA API secara online
5.11 Studi Kasus: Membangkitkan
Karakter Acak
Program komputer dapat mengolah data numerik maupun data
karakter. Anda telah banyak melihat contoh yang melibatkan data numerik. Namun,
adalah juga penting untuk memahami karakter dan bagaimana memprosesnya.
Seperti yang telah diintroduksi pada 2.13, setiap karakter
memiliki Unicode antara 0 sampai FFFF di dalam heksadesimal (65535 dalam
desimal). Untuk membangkitkan karakter acak, diperlukan membangkitkan integer
acak antara 0 sampai 65535 menggunakan ekspresi berikut ini (perhatikan bahwa
karena 0 <= Mat.random() < 1.0,
maka Anda perlu menambahkan 1 pada 65535):
(int)(Math.random()
* (65535 + 1))
Sekarang didiskusikan bagaimana membangkitkan suatu huruf kecil
acak. Unicode atas huruf-huruf kecil adalah integer yang berurutan dari Unicode
‘a’ sampai ‘z’. Unicode atas ‘a’
adalah
(int) ‘a’
Jadi, suatu integer acak dari (int) ‘a’ sampai (int) ‘z’
adalah:
(int)((int)'a'
+ Math.random() * ((int)'z' - (int)'a' + 1)
Seperti yang telah didiskusikan pada 2.13.3 bahwa semua operator
numerik dapat diterapkan terhadap operand-operand char. Operand char dicast menjadi suatu angka bila operand
lainnya adalah suatu angka atau suatu karakter. Jadi, ekspresi sebelumnya dapat
disederhanakan menjadi:
'a' +
Math.random() * ('z' - 'a' + 1)
dan suatu huruf kecil acak adalah
(char)('a'
+ Math.random() * ('z' - 'a' + 1))
Untuk mengeneralisir diskusi ini, disimpulkan bahwa untuk
membangkitkan suatu karakter acak antara ch1
sampai ch2 dengan ch1
< ch2 diperlukan:
(char)(ch1 + Math.random() * (ch2 – ch1 + 1))
Hal ini sederhana tetapi sangat berguna kelak bagi Anda.
Berikutnya akan diciptakan suatu kelas bernama KarakterAcak pada kode5.10 dengan lima metode teroverload untuk
menghasilkan beberapa tipe karakter acak. Anda bisa menggunakan metode-metode
ini dalam proyek perangkat lunak Anda kelak.
Kode5.10 KarakterAcak.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class KarakterAcak {
/** Membangkitkan suatu karakter acak antara
ch1 sampai ch2 */
public static char dapatKarakterAcak(char ch1, char
ch2){
return
(char)(ch1 + Math.random() * (ch2 - ch1 + 1));
}
/** Membangkitkan
suatu huruf kecil acak */
public static char dapatHurufKecilAcak(){
return
dapatKarakterAcak('a', 'z');
}
/** Membangkitkan
suatu huruf besar acak */
public static char dapatHurufBesarAcak(){
return
dapatKarakterAcak('A', 'Z');
}
/** Membangkitkan suatu karakter dijit acak
*/
public static char dapatKarakterDijitAcak(){
return
dapatKarakterAcak('0', '9');
}
/** Membangkitkan suatu karakter acak */
public static char dapatKarakterAcak(){
return dapatKarakterAcak('\u0000',
'\uFFFF');
}
}
|
Kode5.11 memberikan suatu program
uji untuk menampilkan 300 buah huruf kecil acak.
Kode5.11 UjiKarakterAcak.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public class UjiKarakterAcak {
/** Metode utama */
public
static void main(String[] args) {
final
int JUMLAH_KARAKTER = 175;
final
int KARAKTER_PER_BARIS = 25;
// Menampilkan karakter acak 'a' sampai
'z', 25 karakter per baris
for
(int i = 0; i <
JUMLAH_KARAKTER; i++) {
char
ch = KarakterAcak.dapatHurufKecilAcak();
if
((i + 1) % KARAKTER_PER_BARIS == 0)
System.out.println(ch);
else
System.out.print(ch);
}
}
}
|
Keluaran:
zgmivzovjjtbvttdrvqongsry
zhekocyyjbplotalqmptznvzp
fgvbiiahvudvqkqdzbkoyalxx
nyteucdyfexjoifgpbzysudru
nyveanuylhssexnfkeeunbtql
copvntkwlactlnkifldplhgub
gmmyxwmucopsomrscgcnenxiy
nqkvavilpcwofgkrdkadpqkgx
tfqngssyychgzfywcakutthbe
xnmdtlyhmkmyynblfjsoizoid
lshdvsefdkdedlzybdxsuforl
chgnhemgtdizxovnuwlyatdmw
LIJGTUCNFVDBWLDVAYDSZNPCU
YWGTWSCGJEUQVAYMEBXZMKOPN
UJIAAUBTAGATGDCGVMGBHRTMZ
ETAEFQDDUOTQLNTGIBUBLCUSP
VNTCAWYXEAFGNKUKMVXSITINM
DWXBPADHMNMBXAPPFTZAANEYJ
HBJVBGXBDFKDASQEXXRMGHVAX
HBBVCOOEMPJTUECPPYNVHTBGY
FUXBDOBVYTRRNUVVKIHVUCBCD
UJRIVJFIWZZADUFLFRSODUYXR
ALMYDYOROJDHVLXCBVZWULMWM
KNZRISDMZEFLFLDUBKZUPMZGM
Baris 9 memanggil dapatHurufKecilAcak
yang didefinisikan dalam kelas KarakterAcak.
Perhatikan bahwa metode dapatHurufKecilAcak
tidak memiliki parameter, tetapi Anda masih harus menggunakan sepasang
kurung untuk mendefinisikan dan memanggilnya.
5.12 Abstraksi Metode
Kunci untuk mengembangkan perangkat lunak adalah dengan
menerapkan konsep abstraksi. Anda akan belajar banyak level abstraksi dalam
buku ini. Abstraksi metode dicapai dengan memisahkan penggunaan suatu metode
dari implementasinya. Klien dapat menggunakan suatu metode tanpa perlu mengetahui
implementasinya. Detil implementasi dienkapsulasi di dalam metode dan klien
tidak perlu mengetahuinya ketika memanggil metode tersebut. Hal ini disebut
pula dengan penyembunyian informasi
atau enkapsulasi. Jika Anda mengubah
implementasinya, klien tidak akan terpengaruh sepanjang Anda tidak mengubah
sidik metode. Implementasi metode disembunyikan dari klien dalam suatu “kotak
hitam”, seperti ditunjukkan pada Gambar 5.8.
Gambar 5.8 Tubuh metode dapat dianggap sebagai suatu kotak hitam yang
memuat implementasi detil.
Anda telah menggunakan metode System.out.print untuk menampilkan suatu string, dan metode JOptionPane.showInputDialog untuk
membaca suatu string dari suatu kotak dialog, dan metode max untuk mencari nilai maksimum. Anda juga telah mengetahui
bagaimana menuliskan kode untuk memanggil metode-metode tersebut di dalam
program Anda, tetapi sebagai seorang pengguna, Anda tidak syaratkan untuk
mengetahui bagaimana ketiga metode tersebut diimplementasikan.
Konsep abstraksi metode dapat diterapkan pada proses
pengembangan perangkat lunak. Ketika menulis suatu program yang panjang, Anda
bisa menggunakan strategi takluk-dan-bagi,
yang dikenal dengan stepwise refinement,
untuk membagi-bagi program menjadi bagian-bagian kecil dengan masalah-masalah
yang lebih kecil. Berikut akan diterapkan pendekatan takluk-dan-bagi untuk
menampilkan kalender dari bulan tertentu.
5.12.1 Perancangan Top-Down
Bagaimana Anda memulai menulis suatu program? Apakah Anda
langsung memulai mengkode? Banyak programmer pemula seringkali memulai dengan
mencari solusi permasalahan sampai ke tingkat detil. Meskipun kedetilan penting
dalam tahap akhir, namun perhatian yang terlalu tertuju pada kedetilan dapat
menghambat proses penyelesaian-masalah. Untuk membuat langkah penyelesaian
masalah selancar mungkin, contoh ini dimulai dengan menerapkan abstraksi metode
untuk mengisolasi kedetilan dari perancangan.
Pada contoh ini, masalah dibagi menjadi dua submasalah:
mendapatkan masukan dari pengguna, dan menampilkan kalender bulan yang diminta.
Pada tahap ini, Anda harus memfokuskan pada apa yang dicapai oleh submasalah
ini, bukan pada bagaimana mendapatkan masukan dari pengguna atau bagaimana
menampilkan kalender bulan. Anda kemudian dapat menggambarkan suatu struktur
agar menolong Anda memvisualisasikan bagaimana mendekomposisi masalah (lihat
Gambar 5.9a).
Gambar 5.9 Struktur yang menunjukkan bahwa masalah tampilKalender dibagi menjadi dua submasalah, bacaMasukan dan tampilBulan,
dan tampilBulan dibagi lagi menjadi
submasalah yang lebih kecil, tampilJudulBulan
dan tampilTubuhBulan
Masalah menampilkan kalender dari bulan yang diberikan dapat
dibagi menjadi dua submasalah: menampilkan judul bulan, dan menampilkan tubuh
bulan, seperti yang ditunjukkan pada Gambar 5.9b. Judul bulan memuat tiga
baris: bulan dan tahun, garis sambung, dan nama-nama hari dalam seminggu. Anda
perlu mendapatkan nama bulan (misalnya, Januari) dari bulan numerik (misalnya,
1). Hal ini dicapai dalam dapatNamaBulan
(Gambar 5.10a).
Gambar 5.10 (a) Untuk tampilJudulBulan,
dibutuhkan dapatNamaBulan. (b) tampilTubuhBulan dibagi menjadi
submasalah yang lebih kecil
Untuk menampilkan tubuh bulan, Anda perlu mengetahui hari
pertama dalam sebulan (dapatHariMulai) dan berapa banyak hari dalam sebulan (dapatJlhHariDalamSebulan), seperti yang
ditunjukkan pada Gambar 5.10b. Sebagai contoh, Desember 2005 memiliki 31 hari,
dan 1 Desember 2005 adalah hari Kamis.
Bagaimana Anda mendapatkan hari pada tanggal pertama tiap
bulannya? Ada beberapa cara melakukannya. Untuk sementara ini, Anda bisa
menggunakan pendekatan berikut ini. Diasumsikan bahwa Anda mengetahui hari awal
(hariMulai1800 = 3) untuk 1 Januari
1800 yang merupakan hari Rabu. Anda kemudian dapat menghitung total jumlah hari
(totalJumlahHari) dari 1 Januari
1800 sampai tanggal awal bulan kalender. Hari mulai bulan kalender adalah (totalJumlahHari + hariMulai1800) % 7
karena setiap minggu memiliki tujuh hari. Masalah dapatHariMulai kemudian dispesifikasi sebagai dapatTotalJumlahHari, seperti yang ditampilkan pada Gambar 5.11a.
Gambar 5.11 (a) Untuk dapatHariMulai,
Anda membutuhkan dapatTotalJumlahHari.
(b) dapatTotalJumlahHari
didekomposisi menjadi dua submasalah yang lebih kecil.
Gambar 5.12 Struktur yang menunjukkan hubungan hirarki antar submasalah
dalam program
Untuk mendapatkan total jumlah hari, Anda perlu mengetahui
apakah tahun tersebut leap atau tidak dan jumlah hari pada masing-masing bulan.
Jadi dapatTotalJumlahHari kemudian
didekomposisi menjadi dua submasalah: apaTahunLeap
dan dapatJlhHariDalamSebulan, seperti
yang ditampilkan pad Gambar 5.11b. Struktur yang utuh ditampilkan pada Gambar
5.12.
5.12.2 Implementasi Metode
Sekarang perhatian dialihkan kepada implementasi. Pada umumnya,
suatu submasalah berkaitan dengan implementasi metode. Anda harus memutuskan
modul-modul mana yang diimplementasikan sebagai metode dan mana yang perlu
digabungkan dengan metode-metode lain. Keputusan ini hendaknya didasarkan pada
apakah keseluruhan program nantinya akan mudah dibaca atau tidak. Pada contoh
ini, submasalah bacaMasukan dapat
diletakkan pada metode main saja.
Pertama-tama, Anda perlu mengimplementasikan metode main, baru kemudian metode tampilBulan. Jadi, program Anda akan
tampak seperti ini:
public
class TampilKalender
{
/** Metode utama */
public static void main(String[] args) {
Scanner masukan = new Scanner(System.in);
// Meminta pengguna memasukkan tahun
System.out.print("Masukkan tahun (misalnya,
2001): ");
int tahun = masukan.nextInt();
// Meminta pengguna memasukkan bulan
System.out.print("Masukkan bulan
antara 1 sampai 12: ");
int bulan = masukan.nextInt();
// Menampilkan kalender untuk bulan dan
tahun yang diminta
tampilBulan(tahun, bulan);
}
/** Konsep implementasi tampilBulan */
public
static void tampilBulan(int tahun, int bulan){
System.out.print(bulan + " " +
tahun);
}
/** Konsep implementasi tampilJudulBulan */
public
static void tampilJudulBulan
(int tahun, int bulan)
{
}
/** Konsep implementasi dapatTubuhBulan */
public
static void dapatTubuhBulan(int tahun, int bulan)
{
}
/** Konsep implementasi dapatNamaBulan */
public
static String dapatNamaBulan(int bulan)
{
return "January";
}
/** Konsep implementasi dapatHariMulai */
public
static int dapatHariMulai(int tahun, int bulan)
{
return 1;
}
/** Konsep implementasi dapatTotalJumlahHari */
public static int dapatTotalJumlahHari(int tahun, int bulan)
{
return 10000;
}
/** Konsep implementasi dapatJlhHariDalamSebulan
*/
public
static int dapatJlhHariDalamSebulan(int tahun, int bulan)
{
return 31;
}
/** Konsep implementasi apaTahunLeap */
public static boolean apaTahunLeap(int year)
{
return true;
}
}
Anda bisa mengkompilasi program di atas dan melihat apakah ada
error yang terjadi. Selanjutnya akan disajikan detil implementasi metode.
5.12.3 Detil Implementasi
Metode apaTahunLeap
dapat diimplementasikan menggunakan kode berikut ini:
return (tahun % 400 == 0 ||
(tahun % 4 == 0 && tahun % 100 != 0));
Untuk mengimplementasikan dapatJlhHariDalamSebulan, Anda harus memahami
fakta-fakta sebagai berikut:
·
Januari, Maret, Mei, Juli, Agustus,
Oktober, dan Desember memiliki 31 hari.
·
April, Juni, September, dan Nopember memiliki
30 hari.
·
Pebruari memiliki 28 hari pada tahun
reguler dan 29 hari pada tahun leap. Oleh karena itu, pada tahun reguler
terdiri-dari 365 hari, dan pada tahun leap 366 hari.
Berikut program utuh diberikan pada kode5.12.
Kode5.12 TampilKalender.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
import java.util.Scanner;
public class TampilKalender {
/** Metode utama */
public static void main(String[] args) {
Scanner masukan = new Scanner(System.in);
// Meminta pengguna
memasukkan tahun
System.out.print("Masukkan
tahun (misalnya, 2001): ");
int tahun = masukan.nextInt();
// Meminta pengguna
memasukkan bulan
System.out.print("Masukkan bulan antara 1 sampai 12:
");
int bulan = masukan.nextInt();
// Menampilkan
kalender untuk bulan dan tahun yang diminta
tampilBulan(tahun, bulan);
}
/** Konsep
implementasi tampilBulan */
public static void tampilBulan(int tahun, int bulan){
// Menampilkan
kepala kalender
tampilJudulBulan(tahun, bulan);
// Menampilkan tubuh
kalender
tampilTubuhBulan(tahun, bulan);
}
/** Konsep
implementasi tampilJudulBulan */
public static void tampilJudulBulan (int tahun, int bulan) {
System.out.println(" " +
dapatNamaBulan(bulan)
+ " " + tahun);
System.out.println("—————————————————————————————-———-———-———-——");
System.out.println(" Minggu Senin Selasa Rabu Kamis Jumat
Sabtu");
}
/** Konsep
implementasi dapatTubuhBulan */
public static void tampilTubuhBulan(int tahun, int
bulan) {
// Mendapatkan hari
awal tanggal pertama tiap bulan
int
hariMulai = dapatHariMulai(tahun,
bulan);
// Get number of
days in the month
int
jumlahHariDalamSebulan = dapatJlhHariDalamSebulan(tahun,
bulan);
// Padding spasi sebelum hari pertama tiap
bulan
int
i = 0;
for
(i = 0; i < hariMulai; i++)
System.out.print(" ");
for
(i = 1; i <= jumlahHariDalamSebulan; i++) {
System.out.printf("%6d", i);
if
((i + hariMulai) % 7 == 0)
System.out.println();
}
System.out.println();
}
/** Konsep
implementasi dapatNamaBulan */
public static String dapatNamaBulan(int bulan)
{
String namaBulan =
" ";
switch (bulan) {
case
1: namaBulan = "Januari";
break;
case
2: namaBulan = "pebruari";
break;
case
3: namaBulan = "Maret";
break;
case
4: namaBulan = "April";
break;
case
5: namaBulan = "Mei";
break;
case
6: namaBulan = "Juni";
break;
case
7: namaBulan = "Juli";
break;
case
8: namaBulan = "Agustus";
break;
case
9: namaBulan = "September";
break;
case
10: namaBulan = "Oktober";
break;
case
11: namaBulan = "Nopember";
break;
case
12: namaBulan = "Desember";
}
return
namaBulan;
}
/** Konsep
implementasi dapatHariMulai */
public static int dapatHariMulai(int tahun, int
bulan) {
final int HARI_MULAI_JAN_1_1800 = 3;
// Mendapatkan total jumlah hari sejak
1/1/1800 ke bulan/1/tahun
int
totalJumlahHari = dapatTotalJumlahHari(tahun, bulan);
// Kembali ke hari awal bulan/1/tahun
return
(totalJumlahHari + HARI_MULAI_JAN_1_1800) % 7;
}
/** Konsep
implementasi dapatTotalJumlahHari */
public static int dapatTotalJumlahHari(int tahun, int bulan) {
int total = 0;
// Mendapatkan total hari dari 1800 sampai
1/1/year
for
(int i = 1800; i < tahun; i++)
if
(apaTahunLeap(i))
total = total + 366;
else
total = total + 365;
// Menambahkan hari dari Jan sampai bulan
yang diminta
for
(int i = 1; i < bulan; i++)
total = total +
dapatJlhHariDalamSebulan(tahun, i);
return
total;
}
/** Konsep
implementasi dapatJlhHariDalamSebulan */
public static int dapatJlhHariDalamSebulan(int
tahun, int bulan){
if (bulan == 1 || bulan == 3 || bulan == 5 || bulan == 7 ||
bulan == 8 || bulan == 10 || bulan ==
12)
return 31;
if
(bulan == 4 || bulan == 6 || bulan == 9 || bulan == 11)
return 30;
if
(bulan == 2) return
apaTahunLeap(tahun) ? 29 : 28;
return
0; // Jika bulan tidak benar
}
/** Konsep
implementasi apaTahunLeap */
public static
boolean
apaTahunLeap(int tahun) {
return tahun % 400 == 0 || (tahun % 4 == 0 && tahun % 100
!= 0);
}
}
|
Keluaran:
Masukkan
tahun (misalnya, 2001): 2012
Masukkan
bulan antara 1 sampai 12: 11
Nopember
2012
—————————————————————————————-———-———-———-——
Minggu Senin Selasa Rabu Kamis Jumat Sabtu
1 2
3
4
5 6 7
8 9 10
11
12 13 14
15 16 17
18
19 20 21
22 23 24
25
26 27 28
29 30
Masukkan
tahun (misalnya, 2001): 1977
Masukkan
bulan antara 1 sampai 12: 4
April 1977
—————————————————————————————-———-———-———-——
Minggu Senin Selasa Rabu Kamis Jumat Sabtu
1 2
3
4 5 6
7 8 9
10
11 12 13
14 15 16
17
18 19 20
21 22 23
24
25 26 27
28 29 30
No comments:
Post a Comment