Inheritance adalah mekanisme OOP yang memungkinkan sebuah class mewarisi struktur dan perilaku dari class lain. Class yang diwariskan disebut superclass, sementara class yang mewarisi disebut subclass. Subclass otomatis memiliki property dan method milik superclass, dan dapat menambah perilaku baru atau mengganti yang sudah ada. Pada chapter ini kita akan membuka hierarki class sederhana Hewan → Kucing/Anjing, melihat peran keyword open dan override, serta mengamati polymorphism dalam loop.
Mengapa Inheritance Diperlukan #
Tanpa inheritance, setiap class yang serupa harus menulis ulang property dan method yang sama. Class Kucing, Anjing, dan Burung masing-masing akan memiliki property nama dan method deskripsi() yang identik. Ketika hierarki tumbuh, duplikasi ini menjadi sumber bug — perubahan pada satu class tidak otomatis merambat ke class lain.
Inheritance memecahkan masalah ini dengan menempatkan perilaku umum di superclass dan perilaku khusus di subclass. Subclass cukup menulis bagian yang berbeda, sementara bagian yang sama otomatis tersedia dari superclass. Perubahan pada superclass langsung berlaku untuk seluruh subclass.
Sintaks Inheritance Kotlin #
Kotlin menerapkan inheritance secara eksplisit. Tiga aturan utama:
- Class default bersifat
final— tidak dapat diwariskan. Untuk mengizinkan inheritance, tandai superclass dengan keywordopen. - Subclass menandai pewarisan dengan tanda titik dua, diikuti nama superclass dan pemanggilan constructor-nya:
class Kucing(nama: String) : Hewan(nama). - Method yang dapat di-override juga harus ditandai
openpada superclass. Subclass menandai override dengan keywordoverride.
open class Hewan(val nama: String) {
open fun bersuara(): String = "$nama bersuara"
}
class Kucing(nama: String) : Hewan(nama) {
override fun bersuara(): String = "$nama mengeong"
}Pemanggilan : Hewan(nama) pada header class Kucing berarti constructor Kucing mendelegasikan argumen nama ke constructor Hewan. Setelah superclass selesai diinisialisasi, constructor subclass melanjutkan. Subclass otomatis memiliki property nama dari superclass.
Contoh Lengkap Hierarki Hewan #
Contoh berikut mendefinisikan superclass Hewan dengan property nama dan dua method — satu open (bersuara) dan satu final (deskripsi). Subclass Kucing dan Anjing meng-override bersuara dengan implementasi masing-masing, sementara method deskripsi diwarisi apa adanya.
// inheritance.kt
// Mendemonstrasikan inheritance dengan open class, override method, dan super.
open class Hewan(val nama: String) {
open fun bersuara(): String {
return "$nama mengeluarkan suara umum"
}
fun deskripsi(): String {
return "Hewan: $nama"
}
}
class Kucing(nama: String) : Hewan(nama) {
override fun bersuara(): String {
return "$nama mengeong: Meong!"
}
}
class Anjing(nama: String, val ras: String) : Hewan(nama) {
override fun bersuara(): String {
return "$nama ($ras) menggonggong: Guk guk!"
}
}
fun main() {
val kucing = Kucing("Miko")
val anjing = Anjing("Rex", "Husky")
println(kucing.deskripsi())
println(kucing.bersuara())
println(anjing.deskripsi())
println(anjing.bersuara())
println()
println("Loop polimorfik:")
val daftar: List<Hewan> = listOf(kucing, anjing)
for (h in daftar) {
println("- ${h.bersuara()}")
}
}Output yang Dihasilkan:
Hewan: Miko
Miko mengeong: Meong!
Hewan: Rex
Rex (Husky) menggonggong: Guk guk!
Loop polimorfik:
- Miko mengeong: Meong!
- Rex (Husky) menggonggong: Guk guk!Mari kita bedah perilaku inheritance pada kode tersebut:
open class Hewan(val nama: String): keywordopenmengizinkanHewandiwariskan. Tanpaopen, kompilator akan menolak deklarasi subclass.open fun bersuara(): String: method ditandaiopensehingga subclass dapat menggantinya. Methoddeskripsitidak ditandaiopen, sehingga tidak dapat di-override.class Kucing(nama: String) : Hewan(nama): subclass mewarisiHewan. Tanda titik dua diikuti pemanggilan constructor superclass. ConstructorKucingmenerimanamadan meneruskannya ke constructorHewan.override fun bersuara(): String: keywordoverridemenandai method yang menggantikan implementasi superclass. Saat runtime, pemanggilankucing.bersuara()akan memilih implementasiKucingmeskipun variabel bertipeHewan.class Anjing(nama: String, val ras: String) : Hewan(nama): subclass dapat menambah property baru (ras) yang tidak ada di superclass. Propertyrashanya tersedia pada instanceAnjing, bukanHewansecara umum.val daftar: List<Hewan> = listOf(kucing, anjing): variabel bertipeList<Hewan>dapat menampung objectKucingdanAnjing. Loopfor (h in daftar)memanggilh.bersuara()dan runtime memilih implementasi yang sesuai — ini adalah polymorphism atau dynamic dispatch.
Polymorphism Melalui Referensi Superclass #
Salah satu kekuatan utama inheritance adalah polymorphism. Variabel bertipe superclass dapat menampung object subclass apa pun. Saat method open dipanggil melalui variabel tersebut, runtime menentukan implementasi yang sesuai berdasarkan tipe asli object, bukan tipe deklarasi variabel.
Pada loop for (h in daftar), variabel h bertipe Hewan. Namun pemanggilan h.bersuara() menghasilkan teks "Miko mengeong: Meong!" untuk object Kucing dan "Rex (Husky) menggonggong: Guk guk!" untuk object Anjing. Pemilihan implementasi ini dilakukan secara dinamis saat runtime, bukan saat kompilasi.
Aturan Inheritance Penting #
Beberapa aturan yang perlu diingat saat bekerja dengan inheritance Kotlin:
- Semua class secara default
final. Untuk mewariskan, superclass harusopen. - Method juga secara default
final. Untuk dapat di-override, method harusopen. - Keyword
overridewajib di subclass. Tanpaoverride, method dengan nama sama akan menutup (shadow) method superclass alih-alih menggantikannya secara virtual. - Sebuah subclass tetap dapat memanggil implementasi superclass melalui keyword
super(mis.super.bersuara()). - Kelas hanya dapat mewarisi satu superclass langsung. Pewarisan ganda melalui interface akan dibahas pada chapter Interfaces.
Referensi Lanjutan #
- Inheritance
— panduan resmi inheritance dengan keyword
opendanoverride
Ringkasan #
Inheritance di Kotlin bersifat eksplisit — superclass wajib ditandai open, subclass menandai pewarisan dengan titik dua dan pemanggilan constructor superclass. Method yang dapat di-override juga ditandai open, dan subclass menandai override dengan keyword override. Polymorphism terjadi otomatis saat method open dipanggil melalui referensi superclass. Pada chapter open Classes dan Methods berikutnya, kita akan menelusuri lebih dalam mengapa Kotlin memilih class final sebagai default dan implikasi desain yang menyertainya.