Bayangkan perpustakaan yang mendefinisikan class Buku, lalu beberapa bulan kemudian harus mendefinisikan BukuFiksi, BukuReferensi, dan BukuDigital — yang semuanya menyimpan judul, penulis, dan tahun terbit dengan cara yang persis sama. Menyalin-tempel kode keempat class berarti setiap perbaikan bug harus diulang empat kali. Inheritance (pewarisan) memutus masalah tersebut: class baru mewarisi seluruh field dan method class lama, lalu hanya menambahkan bagian yang benar-benar berbeda. Pada Chapter ini kita belajar menyusun hierarki Buku → BukuFiksi, memahami posisi protected di dalamnya, dan membuktikan bahwa seluruh hierarki bermuara pada satu akar: class Object.
extends Membangun Relasi Superclass-Subclass #
Kata kunci extends pada deklarasi class menciptakan relasi pewarisan: class yang diwarisi disebut superclass (atau parent class), class yang mewarisi disebut subclass (atau child class). Subclass memperoleh seluruh member non-private milik superclass — field maupun method — seolah-olah member tersebut ditulis ulang di dalam subclass, tanpa satu baris kode pun benar-benar tersalin. Istilah kekerabatan ini memang lazim: relasinya sering disebut relasi IS-A, karena setiap BukuFiksi adalah Buku.
Mari kita susun superclass-nya terlebih dahulu. Class Buku menyimpan data inti dan method penghitung usia terbit:
class Buku {
private String judul;
private String penulis;
protected int tahunTerbit;
Buku(String judul, String penulis, int tahunTerbit) {
this.judul = judul;
this.penulis = penulis;
this.tahunTerbit = tahunTerbit;
}
public String getJudul() {
return judul;
}
public String getPenulis() {
return penulis;
}
public int usia(int tahunSekarang) {
return tahunSekarang - tahunTerbit;
}
}Perhatikan campuran tingkat aksesnya — ini penerapan langsung Chapter Access Modifiers. Field judul dan penulis tetap private sehingga subclass pun harus melewati getter, sedangkan tahunTerbit sengaja dibuka sebagai protected: subclass boleh menyentuhnya langsung, dunia luar tetap tidak. Subclass-nya kemudian ringkas sekali:
class BukuFiksi extends Buku {
private String genre;
BukuFiksi(String judul, String penulis, int tahunTerbit, String genre) {
super(judul, penulis, tahunTerbit);
this.genre = genre;
}
public String getGenre() {
return genre;
}
public String rekomendasi() {
int usiaBuku = usia(2026);
return genre + " - " + getJudul() + " (" + tahunTerbit
+ "), terbit " + usiaBuku + " tahun lalu";
}
}Hanya genre dan rekomendasi() yang benar-benar baru; seluruh data dan perilaku inti buku tidak ditulis ulang. Pemanggilan super(judul, penulis, tahunTerbit) pada constructor berperan meneruskan inisialisasi data inti ke constructor superclass — mekanismya akan kita bedah tuntas pada Chapter Keyword super.
Bukti Pewarisan dalam Eksekusi #
Program kecil berikut menekan object BukuFiksi dari tiga arah: method warisan, method milik subclass, dan method yang tidak kita tulis di kedua class sama sekali:
public class AplikasiWarisan {
public static void main(String[] args) {
BukuFiksi laskar = new BukuFiksi("Laskar Pelangi", "Andrea Hirata", 2005, "Roman");
System.out.println(laskar.getJudul());
System.out.println(laskar.rekomendasi());
System.out.println("Asal class : " + laskar.getClass().getName());
System.out.println("turunan Object? " + (laskar instanceof Object));
}
}Output yang Dihasilkan:
Laskar Pelangi
Roman - Laskar Pelangi (2005), terbit 21 tahun lalu
Asal class : BukuFiksi
turunan Object? trueMari kita bedah tiga arah tersebut satu per satu:
- Baris 6 (
laskar.getJudul()): methodgetJudultidak ada diBukuFiksi— baris ini bekerja karena methodpublicsuperclass dapat dipanggil lewat object subclass. Kode reuse terjadi secara nyata: satu implementasi, banyak pemakai. - Baris 7 (
laskar.rekomendasi()): method milik subclass ini memanggilusia(2026)dangetJudul()tanpa awalan apa pun — dua method warisan dipakai dari dalam subclass seolah miliknya sendiri, termasuk fieldprotectedtahunTerbityang tersentuh langsung di baris penyusun teks. - Baris 9 (
laskar.getClass().getName()): tidak satu pun class kita mendefinisikangetClass— method ini diwarisi darijava.lang.Object. Hasil cetaknyaBukuFiksimembuktikan methodObjectbekerja pada object subclass kita. - Baris 10 (
laskar instanceof Object): operatorinstanceofmenguji tipe object nyata, dan hasilnyatrue— setiapBukuFiksiadalahBuku, dan setiapBukuadalahObject.
Satu Parent, Satu Akar #
Dua aturan struktural menaungi seluruh hierarki class Java. Pertama, single inheritance: satu class hanya boleh meng-extends tepat satu superclass — sintaks class C extends A, B {} bahkan tidak ada di tata bahasa Java (compiler melaporkannya sebagai galat sintaks '{'' expected). Kebijakan ini sengaja diambil untuk menghindari kerumitan pewarisan ganda, dan kebutuhan “menggabungkan kemampuan dari beberapa sumber” dilayani oleh interface yang akan kita bahas pada Chapter khusus. Kedua, satu akar bersama: class yang ditulis tanpa extends secara implisit merupakan subclass dari java.lang.Object, sehingga seluruh class di Java — buatan kita maupun pustaka standar — membentuk satu pohon keluarga besar berakar pada Object. Method getClass() pada percobaan kita tadi adalah bukti hidupnya.
Pewarisan memberi subclass seluruh warisan superclass, tetapi satu pertanyaan penting belum terjawab: bagaimana constructor superclass dilibatkan saat subclass dijadikan? Data inti buku harus diinisialisasi oleh class yang memilikinya, dan Java mengaturnya lewat panggilan super(...) — lengkap dengan aturan “wajib pernyataan pertama” dan konsekuensi bila parent tak lagi punya constructor tanpa argumen. Chapter berikutnya mengupasnya sampai ke pesan error-nya.
Referensi #
- Oracle: dev.java — Object-Oriented Programming
- Java Language Specification — Chapter 8: Classes
- API java.base — java.lang.Object
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
AplikasiWarisan.java
Unduh berkaspublic class AplikasiWarisan {
public static void main(String[] args) {
BukuFiksi laskar = new BukuFiksi("Laskar Pelangi", "Andrea Hirata", 2005, "Roman");
System.out.println(laskar.getJudul());
System.out.println(laskar.rekomendasi());
System.out.println("Asal class : " + laskar.getClass().getName());
System.out.println("turunan Object? " + (laskar instanceof Object));
}
}
Buku.java
Unduh berkasclass Buku {
private String judul;
private String penulis;
protected int tahunTerbit;
Buku(String judul, String penulis, int tahunTerbit) {
this.judul = judul;
this.penulis = penulis;
this.tahunTerbit = tahunTerbit;
}
public String getJudul() {
return judul;
}
public String getPenulis() {
return penulis;
}
public int usia(int tahunSekarang) {
return tahunSekarang - tahunTerbit;
}
}
BukuFiksi.java
Unduh berkasclass BukuFiksi extends Buku {
private String genre;
BukuFiksi(String judul, String penulis, int tahunTerbit, String genre) {
super(judul, penulis, tahunTerbit);
this.genre = genre;
}
public String getGenre() {
return genre;
}
public String rekomendasi() {
int usiaBuku = usia(2026);
return genre + " - " + getJudul() + " (" + tahunTerbit
+ "), terbit " + usiaBuku + " tahun lalu";
}
}