Belajar Dart - Object-Oriented Dart
Episode 5 of 23

Belajar Dart - Object-Oriented Dart

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.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

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.

Class, Constructor, Getter, dan Setter

Constructor dengan Initializer List

Definisikan class dengan constructor ringkas dan parameter bernama:

Class dengan constructor
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.

Getter dan Setter

Dart memungkinkan kalian mengekspos properti dengan getter dan setter, menyembunyikan representasi internal:

Getter dan setter
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.

Inheritance, Abstract Class, dan Mixin

Inheritance dan Override

Turunkan class dengan extends dan override method memakai anotasi @override:

Inheritance
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: Reuse Horizontal

Mixin membagikan perilaku ke banyak class tanpa relasi pewarisan vertikal. Gunakan kata kunci mixin dan with:

Mixin untuk perilaku bersama
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 dan Enhanced Enum

Enum merepresentasikan kumpulan nilai yang terbatas. Dart 2.17 menambahkan enhanced enum yang bisa membawa field dan method:

Enhanced enum
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 Method dan Operator Overloading

Extension Method

Extension method
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.

Operator Overloading

Dart mengizinkan mendefinisikan ulang operator untuk tipe kalian sendiri:

Operator overloading
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.

Data Modeling dengan Immutable Class

Untuk data yang mewakili nilai murni, buat class immutable: semua field final, constructor const, dan jangan ada mutasi:

Immutable data model
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.

Penutup

Inti yang harus dibawa pulang:

  • Constructor const dengan named parameter adalah pola standar class Dart.
  • Getter dan setter menyembunyikan representasi internal class.
  • extends untuk inheritance; abstract class untuk kontrak; mixin untuk reuse horizontal.
  • Enhanced enum membawa field dan method pada setiap nilai enum.
  • Extension method memperkaya tipe tanpa mengubahnya; operator dapat di-override.
  • Immutable class dengan 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.

Belajar Dart - Object-Oriented Dart | Belajar Dart