Tipe enum adalah jenis kelas khusus yang digunakan untuk merepresentasikan kumpulan nilai konstan dengan jumlah tetap.
Semua enum akan mewarisi kelas Enum secara otomatis. Selain itu, enum termasuk tipe sealed: tidak bisa diwariskan, diimplementasikan, ditambahkan sebagai mixin, dan tidak dapat diinstansiasi secara eksplisit secara manual.
Kelas abstrak dan mixin dapat mengimplementasikan atau mewarisi Enum secara eksplisit, namun tidak mungkin membuat objek nyata dari kelas atau mixin tersebut kecuali diimplementasikan atau disisipkan dalam deklarasi enum.
Gunakan kata kunci enum lalu daftarkan semua konstanta enum untuk mendeklarasikan enum sederhana:
enum Color { red, green, blue }
Saat mendeklarasikan enum, koma di akhir daftar nilai diperbolehkan, hal ini memudahkan proses salin tempel dan mengurangi kesalahan kode.
Enum yang diperluas (Enhanced enums)
Dart mendukung enum yang diperluas. Anda bisa mendeklarasikan field anggota, metode, dan konstruktor konstan layaknya kelas biasa, namun instansinya hanya bisa berupa konstanta tetap yang sudah didefinisikan di awal.
Terdapat serangkaian batasan wajib saat mendeklarasikan enum yang diperluas:
- Variabel instan harus menggunakan modifier
final(termasuk variabel yang dibawa dari mixin) - Semua konstruktor generatif harus diberi label
const - Konstruktor pabrik hanya boleh mengembalikan instansi konstanta yang sudah didefinisikan di dalam enum
- Tidak boleh secara eksplisit mewarisi kelas lain (pewarisan
Enumterjadi secara otomatis) - Tidak boleh menimpa ulang
index,hashCode, serta operator kesetaraan== - Tidak boleh mendeklarasikan anggota bernama
valuesdi dalam enum, karena akan bertabrakan dengan aksesor statisvaluesyang dibuat otomatis - Semua instansi enum harus ditulis di bagian paling awal definisi, dan minimal harus ada satu instansi
- Dalam metode instansi enum yang diperluas, kata kunci
thisdigunakan untuk merujuk pada konstanta enum saat ini
Contoh
enum Vehicle implements Comparable<Vehicle> {
car(tires: 4, passengers: 5, carbonPerKilometer: 400),
bus(tires: 6, passengers: 50, carbonPerKilometer: 800),
bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0);
const Vehicle({
required this.tires,
required this.passengers,
required this.carbonPerKilometer,
});
final int tires;
final int passengers;
final int carbonPerKilometer;
// Getter
int get carbonFootprint => (carbonPerKilometer / passengers).round();
bool get isTwoWheeled => this == Vehicle.bicycle;
@override
int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint;
}
Dart 3.13 ke atas mendukung konstruktor utama untuk menyederhanakan penulisan enum yang diperluas:
enum Vehicle(
final int tires,
final int passengers,
final int carbonPerKilometer,
) implements Comparable<Vehicle> {
car(4, 5, 400),
bus(6, 50, 800),
bicycle(2, 1, 0);
int get carbonFootprint => (carbonPerKilometer / passengers).round();
bool get isTwoWheeled => this == Vehicle.bicycle;
@Override
int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint;
}
Menggunakan Enum
Cara mengakses konstanta enum sama seperti mengakses variabel statis:
final favoriteColor = Color.blue;
if (favoriteColor == Color.blue) {
print('Your favorite color is blue!');
}
Properti index
Setiap konstanta enum memiliki properti index yang mengembalikan nomor urut mulai dari angka 0 sesuai urutan deklarasi enum:
assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);
Konstanta statis values
Gunakan sintaks NamaEnum.values untuk mendapatkan daftar yang berisi semua nilai enum:
List<Color> colors = Color.values;
assert(colors[2] == Color.blue);
Menggunakan enum bersama switch
Ketika menggunakan enum di dalam perintah switch, kompiler akan memberikan peringatan jika belum menangani semua cabang enum. Anda bisa menggunakan default sebagai penutup.
var aColor = Color.blue;
switch (aColor) {
case Color.red:
print('Red as roses!');
case Color.green:
print('Green as grass!');
default:
print(aColor); // Color.blue
}
Properti name
Dengan .name kita dapat mengambil nama string dari konstanta enum:
print(Color.blue.name); // Menampilkan "blue"
Mengakses anggota buatan enum
Pada enum yang diperluas, kita bisa mengakses field, getter, dan metode buatan layaknya objek biasa:
print(Vehicle.car.carbonFootprint);
Berikut contoh lengkap dari pelajaran ini. Kita akan membuat kelas enum bulan dengan menerapkan semua materi yang sudah dipelajari di atas.
enum Month implements Comparable<Month> {
january(1, '一月', days: 31),
february(2, '二月', days: 28),
march(3, '三月', days: 31),
april(4, '四月', days: 30),
may(5, '五月', days: 31),
june(6, '六月', days: 30),
july(7, '七月', days: 31),
august(8, '八月', days: 31),
september(9, '九月', days: 30),
october(10, '十月', days: 31),
november(11, '十一月', days: 30),
december(12, '十二月', days: 31);
const Month(this.monthNumber, this.cnName, {required this.days});
/// Nomor bulan kalender masehi 1~12
final int monthNumber;
/// Nama dalam Bahasa Mandarin
final String cnName;
/// Jumlah hari di tahun biasa
final int days;
/// Getter: Apakah masuk kuartal pertama
bool get isFirstQuarter => monthNumber <= 3;
/// Getter: Apakah memiliki 31 hari
bool get has31Days => days == 31;
/// Metode buatan: Cek apakah Februari pada tahun kabisat
bool isLeapYearFebruary(int year) {
if (this != Month.february) return false;
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
/// Implementasi Comparable untuk dukungan pengurutan
@Override
int compareTo(Month other) {
return monthNumber - other.monthNumber;
}
}
void main() {
// 1. Akses dasar konstanta enum
Month current = Month.august;
print('Enum saat ini:$current');
print('Properti name enum:${current.name}');
print('Bulan:${current.cnName}');
print('Nomor bulan 1~12:${current.monthNumber}');
print('Jumlah hari tahun biasa:${current.days}');
print('Apakah bulan dengan 31 hari:${current.has31Days}');
print('Apakah kuartal pertama:${current.isFirstQuarter}');
// 2. Properti index (indeks urutan deklarasi enum mulai dari 0)
print('\n${Month.january.name} index = ${Month.january.index}');
print('${Month.december.name} index = ${Month.december.index}');
// 3. Mengambil daftar semua enum melalui values
List<Month> allMonths = Month.values;
print('\nTotal ada ${allMonths.length} bulan');
// 4. Menggunakan enum di switch
print('\n==== Pengecekan switch ====');
switch (current) {
case Month.january:
print('Awal tahun');
case Month.february:
print('Bisa ada tahun kabisat');
case Month.march:
case Month.april:
case Month.may:
print('Musim semi');
case Month.june:
case Month.july:
case Month.august:
print('Musim panas');
case Month.september:
case Month.october:
case Month.november:
print('Musim gugur');
case Month.december:
print('Akhir tahun, musim dingin');
}
// 5. Panggil metode buatan
Month feb = Month.february;
print('\nApakah Februari kabisat pada tahun 2024:${feb.isLeapYearFebruary(2024)}');
print('Apakah Februari kabisat pada tahun 2025:${feb.isLeapYearFebruary(2025)}');
// 6. Pengurutan enum (mengandalkan antarmuka Comparable)
var selected = [Month.october, Month.january, Month.july];
selected.sort();
print('\nBulan setelah diurutkan:${selected.map((m) => m.cnName).toList()}');
}
Hasil eksekusi
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Enum saat ini:Month.august
Properti name enum:august
Bulan:八月
Nomor bulan1~12:8
Jumlah hari tahun biasa:31
Apakah bulan dengan 31 hari:true
Apakah kuartal pertama:false
january index = 0
december index = 11
Total ada 12 bulan
==== Pengecekan switch ====
Musim panas
Apakah Februari kabisat pada tahun 2024:true
Apakah Februari kabisat pada tahun 2025:false
Bulan setelah diurutkan:[一月, 七月, 十月]
Enum