Sejauh ini setiap class kita hanya mewarisi dari satu induk. Python sebenarnya mengizinkan lebih: sebuah class bisa mewarisi dua, tiga, atau lebih class sekaligus — fitur bernama multiple inheritance. Sebagian bahasa OOP (Java, misalnya) melarangnya untuk class biasa; Python justru menjadikannya fondasi bagi pola desain yang sangat produktif, yaitu mixin. Kuatnya besar, tetapi dayanya juga bisa berbahaya: begitu dua induk membawa method bernama sama, muncullah pertanyaan “versi mana yang menang?” Chapter ini memperkenalkan sintaksnya, bentuk paling terkenal dari konfliknya (diamond problem), dan cara pemakaian yang aman lewat mixin.
Sintaks Dasar #
Daftar induk ditulis di dalam tanda kurung, dipisahkan koma, dan dibaca dari kiri ke kanan:
class Penulis:
def menulis(self):
return "menulis naskah"
class Pengajar:
def mengajar(self):
return "mengajar kelas"
class PenulisPengajar(Penulis, Pengajar):
pass
budi = PenulisPengajar()
print(budi.menulis())
print(budi.mengajar())Output yang Dihasilkan:
menulis naskah
mengajar kelasObject budi mewarisi method dari kedua induknya: menulis() berasal dari Penulis, mengajar() dari Pengajar. Selama kedua induk tidak bertabrakan nama, semuanya berjalan mulus — class gabungan ini memang benar-benar gabungan dari dua sumber.
Diamond Problem #
Kesulitan muncul ketika jalur pewarisan membentuk belah ketupat: dua induk yang sama-sama turunan dari satu kakek. Bentuk ini disebut diamond problem — masalah klasik semua bahasa yang mengizinkan multiple inheritance:
D mewarisi B dan C; keduanya mewarisi A. Method sapa() ada di A, di-override di C, dan tidak disentuh di B. Dari mana D mendapatkan sapa()?
class A:
def sapa(self):
return "sapa dari A"
class B(A):
pass
class C(A):
def sapa(self):
return "sapa dari C"
class D(B, C):
pass
d = D()
print(d.sapa())Output yang Dihasilkan:
sapa dari CJawabannya: sapa dari C. Banyak yang menduga A — karena B (induk pertama D) langsung di bawah A. Ternyata tidak: Python memakai jalur pencarian D → B → C → A, sehingga C ditemukan lebih dulu daripada A. Jalur pasti inilah yang dibedah pada Chapter Method Resolution Order — dan jalur tersebut juga yang membuat fungsi super() berperilaku mengejutkan di Chapter super().
Pola Mixin #
Pemakaian multiple inheritance yang paling sehat di ekosistem Python adalah mixin: class kecil yang membawa satu kemampuan spesifik, tidak dimaksudkan berdiri sendiri, lalu “dilewarkan” ke class lain. Contoh klasiknya, mixin pencatat log:
class LogMixin:
def log(self, pesan):
print(f"[LOG] {self.__class__.__name__}: {pesan}")
class Buku(LogMixin):
def __init__(self, judul):
self.judul = judul
def pinjam(self, peminjam):
self.log(f"'{self.judul}' dipinjam oleh {peminjam}")
return f"{self.judul} dipinjam oleh {peminjam}"
class Anggota(LogMixin):
def __init__(self, nama):
self.nama = nama
def daftar(self):
self.log(f"anggota baru terdaftar: {self.nama}")
return f"Anggota {self.nama} terdaftar"
buku = Buku("Laskar Pelangi")
anggota = Anggota("Budi")
print(buku.pinjam("Budi"))
print(anggota.daftar())Output yang Dihasilkan:
[LOG] Buku: 'Laskar Pelangi' dipinjam oleh Budi
Laskar Pelangi dipinjam oleh Budi
[LOG] Anggota: anggota baru terdaftar: Budi
Anggota Budi terdaftarMari kita telaah cara kerjanya:
- Baris 1 (
class LogMixin:): mixin hanya berisi satu method, tanpa__init__dan tanpa data. Nama class kebiasaannya diakhiriMixinagar niatnya terbaca. - Baris 3 (
self.__class__.__name__): attribute ini membaca nama class milik object pemanggil, sehingga satu mixin yang sama mencetakBukuuntuk buku danAnggotauntuk anggota. - Baris 5 (
class Buku(LogMixin):):Bukumelewatkan mixin sebagai induk — dan seketika punya kemampuanlog()tanpa menulis ulang apa pun. - Method
pinjam()dandaftar()keduanya memanggilself.log(...)— kode pencatatan berada di satu tempat, dipakai dua class berbeda.
Bandingkan dengan alternatifnya: menyalin method log() ke tiap class (duplikasi), atau membuat Buku dan Anggota mewarisi satu induk raksasa bernama PencatatLog (relasi is-a yang tidak jujur — buku bukanlah pencatat log).
Peringatan Desain #
Aturan praktis yang dipakai komunitas Python: pewarisan ganda hanya untuk mixin kecil dan berfokus — bukan untuk menggabungkan dua class utuh yang masing-masing membawa banyak attribute dan method. Untuk relasi has-a antara class utuh, composition pada Chapter Composition tetap pilihan pertama. Dengan aturan main itu, kita siap membedah mesin yang menjawab “method mana yang menang”: Method Resolution Order.