Mixin, Enum & Extension
Berbagi perilaku dengan mixin, enum yang kaya fitur (enhanced enum), dan menambah kemampuan class yang sudah ada dengan extension method.
Mixin: menyisipkan perilaku
Dart hanya mengizinkan satu extends. Bagaimana jika beberapa class yang tidak bersaudara butuh kemampuan yang sama? Jawabannya mixin: potongan perilaku yang bisa "ditempelkan" ke banyak class dengan kata with.
mixin Berenang {
void renang() => print('$runtimeType berenang');
}
mixin Terbang {
void terbang() => print('$runtimeType terbang');
}
class Hewan {}
class Bebek extends Hewan with Berenang, Terbang {}
class Ikan extends Hewan with Berenang {}
Bebek().renang();
Bebek().terbang();
Ikan().renang();
Mixin bisa dibatasi dengan on agar hanya dipakai class tertentu, dan tidak punya constructor. Gunakan mixin untuk perilaku yang dipakai lintas hierarki, misalnya logging atau validasi.
Enum dasar
Enum mendefinisikan sekumpulan nilai tetap dan bernama. Lebih aman daripada memakai string atau angka sembarang.
enum Hari { senin, selasa, rabu }
var h = Hari.selasa;
print(h); // Hari.selasa
print(h.name); // selasa
print(h.index); // 1
print(Hari.values); // [Hari.senin, Hari.selasa, Hari.rabu]
var pesan = switch (h) {
Hari.senin => 'Mulai pekan',
Hari.selasa => 'Semangat',
Hari.rabu => 'Tengah pekan',
}; // tanpa _ : compiler memastikan semua nilai ditangani
Enhanced enum: enum dengan data dan method
enum Prioritas {
rendah('Rendah', 1),
sedang('Sedang', 2),
tinggi('Tinggi', 3);
final String label;
final int bobot;
const Prioritas(this.label, this.bobot);
bool get mendesak => bobot >= 3;
static Prioritas dariBobot(int b) =>
values.firstWhere((p) => p.bobot == b, orElse: () => rendah);
}
print(Prioritas.tinggi.label); // Tinggi
print(Prioritas.sedang.mendesak); // false
print(Prioritas.dariBobot(3)); // Prioritas.tinggi
Enum bisa punya field final, constructor const, getter, method, bahkan implements dan with. Pola ini sering dipakai untuk status pesanan, peran pengguna, dan tipe notifikasi.
Extension method: menambah kemampuan class yang sudah ada
Kamu tidak bisa mengubah class String bawaan, tetapi bisa menambahkan method baru lewat extension:
extension StringBantu on String {
String get kapital =>
isEmpty ? this : this[0].toUpperCase() + substring(1);
bool get email => contains('@') && contains('.');
}
extension AngkaBantu on int {
bool get prima {
if (this < 2) return false;
for (int i = 2; i * i <= this; i++) {
if (this % i == 0) return false;
}
return true;
}
String get rupiah => 'Rp $this';
}
print('belajar'.kapital); // Belajar
print('a@b.co'.email); // true
print(7.prima); // true
print(15000.rupiah); // Rp 15000
Di dalam extension, this adalah objek yang dipanggil. Extension juga bisa dibuat untuk List<int>, DateTime, dan class buatanmu sendiri.
Kapan memakai apa?
| Kebutuhan | Pilih |
|---|---|
| Himpunan nilai tetap | enum |
| Berbagi perilaku antar class tak sejenis | mixin |
| Hubungan "adalah sebuah" | extends |
| Menambah helper ke tipe yang sudah ada | extension |
Error umum
The type 'Hari' is not exhaustively matched→ switch pada enum tidak mencakup semua nilai.Mixins can't declare constructors.→ mixin tidak boleh punya constructor.- Extension tidak dipakai → belum meng-
importberkas tempat extension didefinisikan.