Class pada Chapter sebelumnya masih berupa kumpulan data pasif: kita mengisi field dari luar, membacanya dari luar, dan seluruh keputusan ada di tangan kode pemanggil. Padahal kekuatan OOP justru muncul ketika data dan perilaku hidup berdampingan di dalam object. Field menyimpan state — kondisi terkini object — sedangkan method menyimpan perilaku — aturan bagaimana state itu boleh dibaca dan diubah. Pada Chapter ini kita lengkapi class Buku dengan method yang mengelola stok peminjaman, lalu kita selidiki apa yang sebenarnya terjadi pada field yang tidak kita isi nilainya.
State dan Perilaku dalam Satu Class #
Mari kita tinjau ulang class Buku dari sudut pandang baru. Empat field (judul, penulis, tahunTerbit, stok) adalah data yang membuat setiap buku berbeda dari buku lain — itulah state. Tiga method yang akan kita tambahkan (pinjam, kembalikan, tampilkanInfo) adalah tindakan yang masuk akal dilakukan terhadap buku — itulah perilaku. Ketika method menulis stok = stok - 1, method mengubah state object yang sama tempat method tersebut berjalan; tidak perlu lagi memindahkan variabel bolak-balik ke fungsi luar seperti pada gaya prosedural.
class Buku {
String judul;
String penulis;
int tahunTerbit;
int stok;
void pinjam() {
if (stok > 0) {
stok = stok - 1;
System.out.println("Peminjaman " + judul + " berhasil, sisa stok " + stok);
} else {
System.out.println("Peminjaman " + judul + " gagal, stok habis");
}
}
void kembalikan() {
stok = stok + 1;
System.out.println("Pengembalian " + judul + ", stok menjadi " + stok);
}
void tampilkanInfo() {
System.out.println(judul + " (" + tahunTerbit + ") oleh " + penulis
+ " | stok: " + stok);
}
}Perhatikan bahwa nama field dipakai di dalam method tanpa embel-embel apa pun. Method instance selalu berjalan “di atas” satu object tertentu; ketika method pinjam menyebut stok, yang dimaksud adalah field stok milik object pemanggil method tersebut. Object pemanggil inilah yang kelak kita rujuk eksplisit dengan kata kunci this pada Chapter Keyword this.
Method Membaca dan Mengubah State #
Berikut program yang menekan class Buku lewat skenario sibuk: dua peminjaman beruntun, satu permintaan ketika stok habis, lalu satu pengembalian. Perhatikan bahwa main tidak pernah menyentuh field stok secara langsung — seluruh perubahan state mengalir lewat method:
public class AplikasiBuku {
public static void main(String[] args) {
Buku buku = new Buku();
buku.judul = "Hujan Bulan Juni";
buku.penulis = "Sapardi Djoko Damono";
buku.tahunTerbit = 1994;
buku.stok = 2;
buku.tampilkanInfo();
buku.pinjam();
buku.pinjam();
buku.pinjam();
buku.kembalikan();
buku.tampilkanInfo();
}
}Output yang Dihasilkan:
Hujan Bulan Juni (1994) oleh Sapardi Djoko Damono | stok: 2
Peminjaman Hujan Bulan Juni berhasil, sisa stok 1
Peminjaman Hujan Bulan Juni berhasil, sisa stok 0
Peminjaman Hujan Bulan Juni gagal, stok habis
Pengembalian Hujan Bulan Juni, stok menjadi 1
Hujan Bulan Juni (1994) oleh Sapardi Djoko Damono | stok: 1Mari kita bedah baris-per-baris bagian-bagian pentingnya:
- Baris 3-7 (
Buku buku = new Buku();dst.):newmenciptakan object, lalu kita mengisi keempat field-nya dari luar. Pola isi-field-manual ini masih kita pakai karena constructor belum dibahas — pada Chapter Constructors pola ini akan digantikan sepenuhnya. - Baris 9 (
buku.tampilkanInfo();): method membaca keempat field dari objectbukulalu mencetak satu baris ringkasan. Teks yang tercetak mencerminkan state awal: stok2. - Baris 10-11 (
buku.pinjam();): setiap panggilan mengurangistoksebesar satu lewatstok = stok - 1di dalam method. Dua panggilan pertama berhasil — output menunjukkan sisa stok turun dari2ke1, lalu ke0. - Baris 12 (
buku.pinjam();yang ketiga): syaratstok > 0kini bernilaifalse, sehingga method menolak peminjaman dan stok tetap0. Keputusan “stok habis” diambil oleh object sendiri, bukan oleh kode pemanggil — inilah bibit dari encapsulation yang akan kita formalisasikan beberapa Chapter lagi. - Baris 13 (
buku.kembalikan();): method menambahstokkembali menjadi1, dantampilkanInfo()terakhir memperlihatkan state akhir yang konsisten dengan seluruh kejadian sebelumnya.
Nilai Bawaan Field #
Apa yang terjadi jika kita menciptakan object lalu lupa mengisi field-nya? Java tidak membiarkan field berisi sampah memori. Compiler javac dan JVM bekerja sama memastikan setiap field instance otomatis terisi nilai bawaan sebelum object bisa dipakai. Program kecil berikut memeriksa nilai field yang sama sekali tidak diisi:
public class NilaiBawaan {
public static void main(String[] args) {
LembarData data = new LembarData();
System.out.println("int : " + data.jumlah);
System.out.println("double : " + data.harga);
System.out.println("boolean: " + data.aktif);
System.out.println("String : " + data.nama);
}
}
class LembarData {
int jumlah;
double harga;
boolean aktif;
String nama;
}Output yang Dihasilkan:
int : 0
double : 0.0
boolean: false
String : nullTabel berikut merangkum aturan nilai bawaan untuk field sesuai tipenya:
| Tipe field | Nilai bawaan |
|---|---|
byte, short, int, long | 0 |
float, double | 0.0 |
boolean | false |
char | '\u0000' (karakter kosong) |
referensi object (String, array, class lain) | null |
Ketiga angka bawaan dicetak apa adanya, sedangkan field String bernilai null — penanda bahwa referensi tersebut belum menunjuk object apa pun. Nilai null tidak berbahaya selama tidak dipakai; baru saat kode memanggil method lewat referensi null, JVM melempar NullPointerException. Perilaku ini kita bedah tuntas pada Section Exception Handling.
Class Buku kita kini punya data dan perilaku, tetapi masih ada pekerjaan rumah yang mengganggu: main harus mengisi empat field satu per satu setiap kali menciptakan buku, dan tidak ada jaminan kelengkapan — object bisa saja lupa diberi judul dan tetap berstatus buku. Java menyediakan mekanisme khusus yang dijalankan otomatis tepat setelah new mengalokasikan memori: constructor. Chapter berikutnya mengupas mekanisme tersebut sampai ke detail aturan penulisannya.
Referensi #
- Java Language Specification — Chapter 8: Classes
- Oracle: dev.java — Object-Oriented Programming
- API java.base — java.lang.Object
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
AplikasiBuku.java
Unduh berkaspublic class AplikasiBuku {
public static void main(String[] args) {
Buku buku = new Buku();
buku.judul = "Hujan Bulan Juni";
buku.penulis = "Sapardi Djoko Damono";
buku.tahunTerbit = 1994;
buku.stok = 2;
buku.tampilkanInfo();
buku.pinjam();
buku.pinjam();
buku.pinjam();
buku.kembalikan();
buku.tampilkanInfo();
}
}
Buku.java
Unduh berkasclass Buku {
String judul;
String penulis;
int tahunTerbit;
int stok;
void pinjam() {
if (stok > 0) {
stok = stok - 1;
System.out.println("Peminjaman " + judul + " berhasil, sisa stok " + stok);
} else {
System.out.println("Peminjaman " + judul + " gagal, stok habis");
}
}
void kembalikan() {
stok = stok + 1;
System.out.println("Pengembalian " + judul + ", stok menjadi " + stok);
}
void tampilkanInfo() {
System.out.println(judul + " (" + tahunTerbit + ") oleh " + penulis
+ " | stok: " + stok);
}
}
NilaiBawaan.java
Unduh berkaspublic class NilaiBawaan {
public static void main(String[] args) {
LembarData data = new LembarData();
System.out.println("int : " + data.jumlah);
System.out.println("double : " + data.harga);
System.out.println("boolean: " + data.aktif);
System.out.println("String : " + data.nama);
}
}
class LembarData {
int jumlah;
double harga;
boolean aktif;
String nama;
}