menengahoopinheritanceMenengah3 mnt baca

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

javascript
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:

javascript
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 induk

Contoh realistis: akun di aplikasi sekolah

javascript
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

  1. Lupa super() di constructor anak menyebabkan ReferenceError: Must call super constructor before using 'this'. Ini error paling umum di inheritance.
  2. Hierarki terlalu dalam. Batasi dua sampai tiga level: perubahan di puncak hierarki yang dalam merembes ke mana-mana dan membuat kode rapuh.
  3. Pewarisan untuk reuse semata. Kalau class anak tidak benar-benar "adalah sejenis" induknya (misalnya Burung extends Pesawat cuma karena sama-sama bisa terbang), itu desain yang salah. Pertimbangkan komposisi (object memiliki object lain) sebagai alternatif.
  4. Override tanpa super lalu duplikasi logika induk. Kalau hanya menambah perilaku, panggil super.method() lalu tambahkan, jangan salin-tempel isi method induk.
Live Playground
export default function App(): JSX.Element {
  return <h1>Hello world</h1>
}

Edit kode di kiri, preview kanan ter-update otomatis.

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>