Constructor di Dart
Cara membuat object dengan rapi: default, named, dan factory constructor.
Masalah: isi property satu per satu itu melelahkan
Di modul sebelumnya kita mengisi property manual setelah object dibuat:
var s = Siswa();
s.nama = 'Rizky';
s.umur = 17;Kalau propertynya sepuluh, capek. Constructor adalah method khusus yang jalan otomatis saat object dibuat, supaya object langsung terisi rapi sejak lahir.
Constructor dasar
class Siswa {
String nama;
int umur;
Siswa(this.nama, this.umur);
void perkenalkan() {
print('Halo, saya $nama, umur $umur tahun.');
}
}
void main() {
var s = Siswa('Rizky', 17);
s.perkenalkan();
}Siswa(this.nama, this.umur) adalah constructor: namanya sama dengan class, dan this.nama langsung mengisi property dari argumen. Property nama dan umur sekarang wajib diisi saat pembuatan karena tidak punya nilai default. Di sinilah null safety Dart bekerja: property non-nullable harus terisi lewat constructor.
Named constructor
Satu class boleh punya banyak constructor dengan nama berbeda:
class Tanggal {
int hari;
int bulan;
int tahun;
Tanggal(this.hari, this.bulan, this.tahun);
Tanggal.hariIni()
: hari = 8,
bulan = 10,
tahun = 2026;
void cetak() => print('$hari-$bulan-$tahun');
}
void main() {
var t1 = Tanggal(17, 8, 1945);
var t2 = Tanggal.hariIni();
t1.cetak();
t2.cetak();
}Tanggal.hariIni() adalah named constructor. Bagian setelah titik dua (:) disebut initializer list, dipakai untuk mengisi final property atau nilai yang dihitung sebelum badan constructor jalan.
Catatan teknis: Kalau class punya
finalproperty, wajib diisi lewat constructor atau initializer list, tidak bisa diisi belakangan. Ini sering bikin error "field must be initialized" pada pemula. Solusinya selalu sama: tambah parameter constructor atau beri nilai default.
Constructor dengan named parameter
Kombinasi constructor + named parameter adalah pola paling populer di Dart/Flutter:
class Produk {
final String nama;
final double harga;
final int stok;
Produk({required this.nama, required this.harga, this.stok = 0});
void info() => print('$nama: Rp$harga (stok $stok)');
}
void main() {
var p = Produk(nama: 'Kopi', harga: 15000.0);
p.info();
}Perhatikan this.stok = 0: default value bisa langsung ditulis di constructor. Rapi dan aman.
Factory constructor
Kadang pembuatan object butuh logika khusus, mis. cache atau parsing. Factory constructor tidak selalu membuat instance baru:
class Config {
final String mode;
static final Map<String, Config> _cache = {};
factory Config(String mode) {
return _cache.putIfAbsent(mode, () => Config._internal(mode));
}
Config._internal(this.mode); // constructor private
}
void main() {
var a = Config('debug');
var b = Config('debug');
print(identical(a, b)); // true, object yang sama dari cache
}Config._internal adalah constructor private (underscore) yang hanya bisa dipanggil dari dalam class. Factory mengatur kapan memanggilnya. Pola ini dipakai untuk singleton dan object pooling.
Ringkasan
| Jenis | Ciri | Dipakai untuk |
|---|---|---|
| Default | Siswa(...) | pembuatan normal |
| Named | Tanggal.hariIni() | cara alternatif membuat object |
| Factory | factory Config(...) | logika khusus, cache, singleton |
Kuasai tiga ini dan kamu sudah bisa membaca 90% class di codebase Dart/Flutter mana pun.