Inheritance: extends dan super
Kamu sudah bisa membuat class. Sekarang bayangkan butuh class Motor dan Mobil: keduanya punya merek, kecepatan, method maju dan berhenti, tapi motor punya jumlah gigi perseneling sedangkan mobil punya jumlah pintu. Me...
Inheritance: extends dan super
Kamu sudah bisa membuat class. Sekarang bayangkan butuh class Motor dan Mobil: keduanya punya merek, kecepatan, method maju dan berhenti, tapi motor punya jumlah gigi perseneling sedangkan mobil punya jumlah pintu. Menulis ulang semua yang sama di dua class itu duplikasi. Inheritance memungkinkan satu class mewarisi dari class lain.
Kenapa inheritance ada
Prinsipnya DRY (Don't Repeat Yourself). Kalau Motor dan Mobil sama-sama butuh logika maju(), berhenti(), dan validasi kecepatan, logika itu cukup ditulis sekali di class induk Kendaraan. Class anak mewarisi semuanya, lalu menambahkan atau mengubah yang spesifik. Kalau nanti aturan maju() berubah, kamu edit satu tempat saja. Tanpa inheritance, kamu harus ingat mengedit di semua class turunan, dan satu yang terlewat jadi bug.
extends dan super
class Kendaraan {
constructor(merk, kecepatanMaks) {
this.merk = merk;
this.kecepatanMaks = kecepatanMaks;
this.kecepatan = 0;
}
maju(tambah) {
this.kecepatan = Math.min(this.kecepatan + tambah, this.kecepatanMaks);
return `${this.merk} melaju ${this.kecepatan} km/jam`;
}
berhenti() {
this.kecepatan = 0;
return `${this.merk} berhenti`;
}
}
class Motor extends Kendaraan {
constructor(merk, kecepatanMaks, gigi) {
super(merk, kecepatanMaks); // wajib dipanggil dulu
this.gigi = gigi;
}
// method khusus motor
wheelie() {
return `${this.merk} standing!`;
}
}
const beat = new Motor("Honda Beat", 110, 4);
console.log(beat.maju(60)); // warisan dari Kendaraan
console.log(beat.wheelie()); // khusus Motor
console.log(beat.berhenti());extends menyatakan "Motor adalah sejenis Kendaraan". super(...) memanggil constructor induk dan wajib dipanggil sebelum memakai this di constructor anak. Setelah itu, instance Motor bisa memakai semua method Kendaraan seolah miliknya sendiri.
Method overriding: mengubah perilaku warisan
Kadang class anak butuh versi berbeda dari method induk. Tulis ulang method dengan nama sama, dan panggil versi induk dengan super.namaMethod() kalau masih butuh logika aslinya:
class Mobil extends Kendaraan {
constructor(merk, kecepatanMaks, jumlahPintu) {
super(merk, kecepatanMaks);
this.jumlahPintu = jumlahPintu;
this.acMenyala = false;
}
// override: mobil butuh pemanasan AC sebelum melaju kencang
maju(tambah) {
if (tambah > 50 && !this.acMenyala) {
return `${this.merk}: nyalakan AC dulu sebelum ngebut!`;
}
return super.maju(tambah); // pakai logika induk
}
nyalakanAC() {
this.acMenyala = true;
return "AC menyala, kabin dingin";
}
}
const avanza = new Mobil("Avanza", 160, 4);
console.log(avanza.maju(80)); // ditolak, AC belum nyala
console.log(avanza.nyalakanAC());
console.log(avanza.maju(80)); // sekarang bisa, pakai logika indukContoh realistis: akun di aplikasi sekolah
class Pengguna {
constructor(nama, email) {
this.nama = nama;
this.email = email;
}
sapa() {
return `Halo, ${this.nama}`;
}
}
class Guru extends Pengguna {
constructor(nama, email, mapel) {
super(nama, email);
this.mapel = mapel;
}
sapa() {
return super.sapa() + ` (Guru ${this.mapel})`;
}
beriNilai(siswa, nilai) {
return `${this.nama} memberi nilai ${nilai} ke ${siswa}`;
}
}
class SiswaAkun extends Pengguna {
constructor(nama, email, kelas) {
super(nama, email);
this.kelas = kelas;
}
sapa() {
return super.sapa() + ` (Kelas ${this.kelas})`;
}
}
const pakBudi = new Guru("Pak Budi", "[email protected]", "Matematika");
const ani = new SiswaAkun("Ani", "[email protected]", "XII-1");
console.log(pakBudi.sapa()); // Halo, Pak Budi (Guru Matematika)
console.log(ani.sapa()); // Halo, Ani (Kelas XII-1)Login, nama, dan email ditulis sekali di Pengguna. Peran spesifik tinggal di class anak masing-masing.
Jebakan umum
- Lupa
super()di constructor anak menyebabkanReferenceError: Must call super constructor before using 'this'. Ini error paling umum di inheritance. - Hierarki terlalu dalam. Batasi dua sampai tiga level: perubahan di puncak hierarki yang dalam merembes ke mana-mana dan membuat kode rapuh.
- Pewarisan untuk reuse semata. Kalau class anak tidak benar-benar "adalah sejenis" induknya (misalnya
Burung extends Pesawatcuma karena sama-sama bisa terbang), itu desain yang salah. Pertimbangkan komposisi (object memiliki object lain) sebagai alternatif. - Override tanpa super lalu duplikasi logika induk. Kalau hanya menambah perilaku, panggil
super.method()lalu tambahkan, jangan salin-tempel isi method induk.
export default function App(): JSX.Element { return <h1>Hello world</h1> }
Tantangan
Hierarki Pegawai Warung
Di dunia nyata, sistem HRD membedakan pegawai tetap dan pegawai paruh waktu: keduanya punya nama dan gaji pokok, tapi cara hitung gajinya berbeda (paruh waktu dibayar per jam). Tanpa inheritance, rumus gaji pokok ditulis dua kali dan rawan tidak sinkron. Tantangan ini melatihmu memodelkan hierarki yang benar. Buat class Pegawai (nama, gajiPokok, method totalGaji() mengembalikan gajiPokok), lalu PegawaiParuhWaktu extends Pegawai (tambah jamKerja, upahPerJam; override totalGaji() menjadi gajiPokok + jamKerja * upahPerJam).
<!doctype html> <html> <head> <meta charset="utf-8" /> </head> <body> <h1>Halo JS</h1> <p>Buka console preview untuk melihat output.</p> <script src="index.js"></script> </body> </html>