Episode ini membedah object-oriented programming di Dart: class dan constructor, inheritance, mixin, abstract class, dan enum, serta extension method dan operator overloading untuk data modeling yang immutable.

Dart adalah bahasa yang sepenuhnya berorientasi objek: setiap nilai adalah objek, dan setiap objek adalah instance dari sebuah class. Episode 5 membawa kalian ke jantung pemrograman Dart — mendesain tipe yang jelas dan aman lewat class, inheritance, mixin, enum, serta extension.
Kalian akan belajar membangun class dengan constructor modern, mengatur perilaku bersama lewat abstract class dan mixin, memperkaya tipe dengan extension method, serta membuat data model immutable yang bebas efek samping. Penguasaan bagian ini membedakan kalian yang sekadar menulis skrip dengan kalian yang mendesain aplikasi.
Definisikan class dengan constructor ringkas dan parameter bernama:
class Produk {
final String nama;
final double harga;
const Produk({required this.nama, required this.harga});
}
void main() {
const item = Produk(nama: 'Kopi', harga: 25000);
print('${item.nama} seharga ${item.harga}');
}Produk({required this.nama, required this.harga}) adalah constructor yang langsung menginisialisasi field — pola paling umum di codebase Dart modern.
Dart memungkinkan kalian mengekspos properti dengan getter dan setter, menyembunyikan representasi internal:
class Suhu {
double _celsius;
Suhu(this._celsius);
double get fahrenheit => _celsius * 9 / 5 + 32;
set fahrenheit(double f) => _celsius = (f - 32) * 5 / 9;
}Getter fahrenheit menghitung konversi tanpa menyimpan duplikat data, dan field _celsius yang diawali garis bawah bersifat privat per library.
Turunkan class dengan extends dan override method memakai anotasi @override:
abstract class Binatang {
void bersuara();
}
class Kucing extends Binatang {
@override
void bersuara() => print('Meow');
}
void main() {
Binatang hewan = Kucing();
hewan.bersuara();
}abstract class Binatang mendefinisikan kontrak tanpa implementasi; class Kucing mengimplementasikan method bersuara. Polimorfisme memungkinkan Kucing diperlakukan sebagai Binatang.
Mixin membagikan perilaku ke banyak class tanpa relasi pewarisan vertikal. Gunakan kata kunci mixin dan with:
mixin Logger {
void log(String pesan) => print('[LOG] $pesan');
}
class Aplikasi with Logger {}Aplikasi with Logger langsung mendapat method log tanpa harus mewarisi dari class tertentu. Ini alat yang tepat untuk cross-cutting concern seperti logging dan audit.
Enum merepresentasikan kumpulan nilai yang terbatas. Dart 2.17 menambahkan enhanced enum yang bisa membawa field dan method:
enum StatusPesanan {
menunggu('Menunggu pembayaran'),
diproses('Sedang diproses'),
selesai('Selesai');
final String label;
const StatusPesanan(this.label);
}StatusPesanan.diproses.label mengakses field label yang disimpan per nilai enum. Enhanced enum sangat berguna untuk status domain yang butuh data tambahan.
extension Kebalikan on String {
String get dibalik => split('').reversed.join();
}'Dart'.dibalik bekerja seolah-olah String punya getter dibalik, padahal class String tidak pernah diubah. Extension sangat efektif untuk menambahkan utilitas pada tipe dari package lain.
Dart mengizinkan mendefinisikan ulang operator untuk tipe kalian sendiri:
class Vektor {
final int x;
final int y;
const Vektor(this.x, this.y);
Vektor operator +(Vektor lain) => Vektor(x + lain.x, y + lain.y);
@override
String toString() => '($x, $y)';
}
void main() {
var a = Vektor(1, 2) + Vektor(3, 4);
print(a);
}Operator + yang di-override menjumlahkan dua Vektor. Overloading membuat tipe domain terasa seperti primitif, selama dipakai dengan disiplin.
Untuk data yang mewakili nilai murni, buat class immutable: semua field final, constructor const, dan jangan ada mutasi:
class Alamat {
final String jalan;
final String kota;
const Alamat(this.jalan, this.kota);
Alamat copyWith({String? jalan, String? kota}) {
return Alamat(jalan ?? this.jalan, kota ?? this.kota);
}
}
void main() {
const a = Alamat('Jl. Melati', 'Bandung');
var b = a.copyWith(kota: 'Jakarta');
print('$a -> $b');
}Pola copyWith menghasilkan instance baru dengan sebagian field diubah, tanpa memodifikasi instance asli — kunci menghindari bug akibat shared state di aplikasi besar.
Inti yang harus dibawa pulang:
const dengan named parameter adalah pola standar class Dart.extends untuk inheritance; abstract class untuk kontrak; mixin untuk reuse horizontal.copyWith mencegah bug shared state.Di episode 6 selanjutnya kita akan membahas null safety dan sistem tipe — nullable versus non-nullable, operator ?. dan ??, late dan type promotion, serta sound null safety dan tool migrasi. Inilah mekanisme yang membuat Dart terasa aman sejak waktu kompilasi.