oopabstractmixinMenengah5 mnt baca

Abstract Class dan Mixin

Kontrak dengan abstract class, berbagi kemampuan lewat mixin, dan interface implisit.

Abstract class: cetakan yang belum jadi

Kadang class induk terlalu umum untuk dibuat object-nya. Untuk apa bikin object Hewan generik? Yang ada ya kucing atau anjing. Abstract class tidak bisa diinstansiasi, tapi bisa diwarisi:

dart
abstract class Bentuk {
  double luas(); // method tanpa badan: wajib diimplementasi anak
}

class Persegi extends Bentuk {
  double sisi;
  Persegi(this.sisi);

  @override
  double luas() => sisi * sisi;
}

class Lingkaran extends Bentuk {
  double r;
  Lingkaran(this.r);

  @override
  double luas() => 3.14 * r * r;
}

void main() {
  // var b = Bentuk(); // ERROR: abstract tidak bisa dibuat object
  var daftar = <Bentuk>[Persegi(4), Lingkaran(7)];
  for (var b in daftar) {
    print(b.luas());
  }
}

Method tanpa badan seperti double luas(); memaksa setiap anak mengimplementasikannya. Ini namanya kontrak: "kalau kamu mengaku Bentuk, kamu wajib bisa menghitung luas".

Interface implisit: setiap class adalah interface

Di Dart tidak ada keyword interface. Setiap class otomatis bisa dipakai sebagai interface dengan implements:

dart
class Terbang {
  void terbang() => print('Terbang tinggi!');
}

class Burung implements Terbang {
  @override
  void terbang() => print('Mengepakkan sayap...');
}

void main() {
  Burung().terbang();
}

Bedanya dengan extends: implements tidak mewarisi isi, hanya kontraknya. Semua method harus ditulis ulang. Cocok saat kamu cuma butuh kesepakatan tipe tanpa berbagi implementasi.

Mixin: tempel kemampuan

Ingat batasan single inheritance? Mixin adalah jawabannya. Mixin seperti stiker kemampuan yang bisa ditempel ke class mana pun:

dart
class Hewan {
  String nama;
  Hewan(this.nama);
}

mixin BisaRenang {
  void berenang() => print('Berenang dengan gaya bebas!');
}

mixin BisaTerbang {
  void terbang() => print('Terbang melayang!');
}

class Bebek extends Hewan with BisaRenang, BisaTerbang {
  Bebek(String nama) : super(nama);
}

void main() {
  var d = Bebek('Dodi');
  d.berenang();
  d.terbang();
}

Satu class bisa with banyak mixin sekaligus. Mixin tidak punya constructor dan tidak bisa diinstansiasi sendiri.

Catatan teknis: Urutan mixin itu penting kalau ada method yang sama: class A with M1, M2 maka versi M2 yang menang. Aturan umumnya: mixin yang disebut terakhir menimpa yang sebelumnya. Jarang jadi masalah, tapi wajib tahu kalau suatu hari perilakunya terasa aneh.

Kapan pakai apa?

KebutuhanPakai
Hierarki "adalah" + berbagi kodeextends
Kontrak wajib implementasiabstract class
Kontrak tanpa warisi kodeimplements
Berbagi kemampuan ke banyak class tak berkerabatmixin

Contoh nyata: di Flutter, SingleTickerProviderStateMixin ditempel ke State untuk memberi kemampuan animasi. Tanpa mixin, setiap State yang butuh animasi harus extends class khusus dan hierarkinya jadi kaku.

Latihan gabungan

dart
mixin Logger {
  void log(String pesan) => print('[LOG] $pesan');
}

abstract class Kendaraan {
  void jalan();
}

class Mobil extends Kendaraan with Logger {
  @override
  void jalan() {
    log('Mesin dinyalakan');
    print('Mobil melaju...');
  }
}

void main() {
  Mobil().jalan();
}

Di sini Mobil mewarisi kontrak dari Kendaraan sekaligus menempel kemampuan Logger. Tiga konsep dalam satu class kecil.