Perpustakaan tidak hanya mengelola buku umum — ada buku pelajaran, buku referensi, buku digital, semuanya dengan judul, penulis, dan aturan pinjam. Menulis class untuk masing-masing berarti menyalin method deskripsi() dan attribute judul berkali-kali; satu perbaikan kecil harus ditempel ke semua salinan. Inheritance (pewarisan) menyelesaikannya: class anak mewarisi seluruh attribute dan method class induk, lalu menambah atau mengubah bagian yang beda. Kembali ke domain perpustakaan, chapter ini membangun hierarki Buku pertama kita.
Sintaks Dasar Pewarisan #
Relasi pewarisan dinyatakan dengan tanda kurung saat mendefinisikan class: class Anak(Induk):. Class BukuPelajaran berikut tidak berisi apa-apa, tetapi mewarisi segalanya dari Buku:
class Buku:
def __init__(self, judul, penulis):
self.judul = judul
self.penulis = penulis
def deskripsi(self):
return f"{self.judul} karya {self.penulis}"
class BukuPelajaran(Buku):
pass
buku = BukuPelajaran("Matematika SMA Kelas X", "Tim Kemdikbud")
print(buku.deskripsi())Output yang Dihasilkan:
Matematika SMA Kelas X karya Tim KemdikbudMari kita telaah baris-baris kode di atas:
- Baris 9 (
class BukuPelajaran(Buku):):Bukuditulis di dalam kurung, menjadikannya base class (induk). Semua attribute dan methodBukuotomatis tersedia padaBukuPelajaran. - Baris 10 (
pass): class anak belum menambahkan apa pun — semua perilakunya murni warisan. - Baris 12 (
buku = BukuPelajaran(...)): pemanggilan ini menjalankan__init__warisan dariBuku, sehingga object tetap terisijuduldanpenulis. - Baris 14 (
print(buku.deskripsi())): method warisan dipanggil seperti biasa — objectBukuPelajarantidak tahu bedanya.
Dalam istilah pewarisan, Buku disebut parent atau superclass, dan BukuPelajaran disebut child atau subclass.
Override dan Extend dengan super() #
Anak jarang ingin jadi kembaran induknya. Dua kata kunci kerjanya: override (mengganti method warisan dengan versi sendiri) dan extend (menambah attribute atau perilaku baru). Fungsi super() menjadi jembatan — class anak bisa memanggil versi induk tanpa menulis nama induk secara manual:
class Buku:
def __init__(self, judul, penulis):
self.judul = judul
self.penulis = penulis
def deskripsi(self):
return f"{self.judul} karya {self.penulis}"
def durasi_pinjam(self):
return 7
class BukuReferensi(Buku):
def __init__(self, judul, penulis, edisi):
super().__init__(judul, penulis)
self.edisi = edisi
def deskripsi(self):
return f"{super().deskripsi()} (Edisi {self.edisi})"
def durasi_pinjam(self):
return 2
buku = BukuReferensi("Kamus Besar Bahasa Indonesia", "Badan Pengembangan Bahasa", "Keenam")
print(buku.deskripsi())
print("Lama pinjam:", buku.durasi_pinjam(), "hari")Output yang Dihasilkan:
Kamus Besar Bahasa Indonesia karya Badan Pengembangan Bahasa (Edisi Keenam)
Lama pinjam: 2 hariMari kita telaah bagian pentingnya:
- Baris 13-15 (
def __init__padaBukuReferensi): anak menambah parameteredisi. Barissuper().__init__(judul, penulis)memanggil constructor induk agarjuduldanpenulistetap terpasang dengan benar — pola standar extend pada constructor. - Baris 17-18 (
def deskripsi): anak meng-overridedeskripsi, tetapi tetap memakaisuper().deskripsi()untuk bagian yang sudah benar — hasilnya teks induk plus tambahan edisi, tanpa menyalin formatnya. - Baris 20-21 (
def durasi_pinjam): override penuh tanpa memanggil induk — buku referensi memang punya aturan pinjam sendiri (2 hari, bukan 7).
Memeriksa Hubungan dengan issubclass dan isinstance #
Python menyediakan dua fungsi bawaan untuk memeriksa hubungan pewarisan pada runtime:
class Buku:
def __init__(self, judul, penulis):
self.judul = judul
self.penulis = penulis
class BukuReferensi(Buku):
pass
buku = BukuReferensi("Kamus Besar Bahasa Indonesia", "Badan Pengembangan Bahasa")
print(issubclass(BukuReferensi, Buku))
print(issubclass(Buku, BukuReferensi))
print(isinstance(buku, BukuReferensi))
print(isinstance(buku, Buku))Output yang Dihasilkan:
True
False
True
TrueFungsi issubclass() membandingkan dua class — BukuReferensi memang turunan Buku, dan hubungan ini tidak berlaku dua arah. Hasil yang lebih menarik ada di dua baris terakhir: object BukuReferensi terhitung sebagai instance dari Buku juga. Karena anak adalah-versi-khusus dari induk, semua instance anak otomatis memenuhi syarat sebagai instance induk. Fakta inilah yang menjadi bahan bakar polymorphism pada chapter berikutnya.
Pemeriksaan seperti ini bukan hanya alat debugging. Kode aplikasi kerap memakainya untuk mengambil keputusan — misalnya layanan pengiriman notifikasi yang hanya memproses object bertipe BukuReferensi, atau laporan yang mengelompokkan seluruh koleksi berdasarkan kelasnya. Kegunaan terbesarnya tetap pada level desain: jika isinstance(objek, Induk) mengembalikan True untuk semua anak, maka kode yang ditulis melawan induk otomatis bekerja untuk seluruh keluarganya.
Relasi is-a dan Batasnya #
Inheritance sebaiknya dipakai ketika jawaban atas pertanyaan “apakah anak adalah (is-a) induk?” tegas ya. BukuReferensi adalah Buku — masuk akal. Sebaliknya, Mobil bukan Mesin; mobil memiliki (has-a) mesin. Relasi has-a tidak dinyatakan lewat pewarisan, melainkan lewat composition yang dibahas pada Chapter Composition. Aturan praktis ini menyelamatkan banyak hierarki class dari desain yang dipaksakan — dan jika ragu, komposisi hampir selalu pilihan yang lebih aman.