Kelas menyatukan data dan perilaku ke dalam satu tipe, dan seluruh widget Flutter adalah kelas, sehingga keterampilan menulis kelas Dart langsung terpakai saat menyusun widget. Topik ini membahas field, constructor dengan gula sintaks this, constructor bernama, factory constructor yang mengendalikan pembuatan objek, getter, metode, serta const constructor. Satu kelas contoh dijalankan utuh agar setiap mekanismenya terlihat pada keluaran nyata.
Program pertama: kelas Ujian#
Contoh yang digunakan di seluruh topik ini adalah kelas Ujian, yaitu representasi sederhana data nilai ujian per mata pelajaran. Satu berkas memuat definisi kelas beserta fungsi main() yang mencoba setiap fiturnya. Simpan berkas berikut sebagai ujian.dart, lalu jalankan perintah dart ujian.dart dari direktori tempat berkas itu berada.
// Kelas Ujian: constructor, constructor bernama, factory constructor, dan getter.
class Ujian {
final String mataPelajaran;
final double nilai;
// Constructor utama dengan gula sintaks this.
const Ujian(this.mataPelajaran, this.nilai);
// Constructor bernama: mengonversi nilai dari skala 4 ke skala 100.
Ujian.dariSkalaEmpat(String mataPelajaran, double skalaEmpat)
: this(mataPelajaran, skalaEmpat / 4 * 100);
// Factory constructor: satu objek per mata pelajaran disimpan di cache.
static final Map<String, Ujian> _cache = {};
factory Ujian.tercache(String mataPelajaran, double nilai) {
return _cache.putIfAbsent(
mataPelajaran,
() => Ujian(mataPelajaran, nilai),
);
}
// Getter berbentuk ekspresi.
bool get lulus => nilai >= 75;
// Getter dengan tubuh blok.
String get predikat {
if (nilai >= 90) {
return 'A';
}
if (nilai >= 80) {
return 'B';
}
if (nilai >= 70) {
return 'C';
}
return 'D';
}
// Metode biasa.
void tampilkan() {
print('$mataPelajaran: nilai $nilai, predikat $predikat, lulus $lulus');
}
}
void main() {
var matematika = Ujian('Matematika', 87.5);
matematika.tampilkan();
var fisika = Ujian.dariSkalaEmpat('Fisika', 3.2);
fisika.tampilkan();
// Factory: pemanggilan kedua mengembalikan objek yang sudah ada.
var kimiaA = Ujian.tercache('Kimia', 92.0);
var kimiaB = Ujian.tercache('Kimia', 92.0);
kimiaA.tampilkan();
print('kimiaA identik dengan kimiaB: ${identical(kimiaA, kimiaB)}');
// Const constructor: objek konstanta dengan argumen sama dikanonikalisasi.
const seniA = Ujian('Seni', 100.0);
const seniB = Ujian('Seni', 100.0);
print('seniA identik dengan seniB: ${identical(seniA, seniB)}');
}Matematika: nilai 87.5, predikat B, lulus true
Fisika: nilai 80.0, predikat B, lulus true
Kimia: nilai 92.0, predikat A, lulus true
kimiaA identik dengan kimiaB: true
seniA identik dengan seniB: trueKeluaran memperlihatkan tiga jalur pembuatan objek yang berbeda. Matematika dibuat melalui constructor utama, Fisika melalui constructor bernama dariSkalaEmpat yang mengonversi 3.2 pada skala 4 menjadi 80.0, sedangkan Kimia melalui factory constructor tercache. Dua baris terakhir membuktikan identitas objek: pemanggilan Ujian.tercache('Kimia', 92.0) yang kedua mengembalikan objek pertama, dan dua konstanta const dengan argumen sama disatukan Dart menjadi satu objek. Bagian berikut mengurai setiap mekanisme tersebut.
Field dan constructor#
Field adalah variabel yang melekat pada kelas, dan kedua field pada kelas Ujian dinyatakan final sehingga isinya tidak dapat diganti setelah objek dibuat. Kelas yang seluruh field-nya final menghasilkan objek immutable, yaitu objek yang isinya tidak berubah selama objek tersebut ada. Pola ini banyak digunakan di Flutter karena objek yang tidak berubah aman dibagikan antarbagian aplikasi.
Constructor utama const Ujian(this.mataPelajaran, this.nilai); menggunakan gula sintaks this.mataPelajaran, yang sekaligus mendeklarasikan parameter dan mengisinya ke field bernama sama. Tidak perlu menulis tubuh constructor karena pengisiannya sudah lengkap. Kata kunci const pada constructor memungkinkan objek dibuat sebagai konstanta waktu kompilasi, dengan syarat seluruh field-nya final dan argumennya konstanta. Dart menyatukan dua konstanta dengan argumen sama menjadi satu objek, sehingga identical(seniA, seniB) bernilai true. Widget Flutter menggunakan pola yang sama, misalnya const Text('Halo') yang dapat disatukan Dart saat widget dirender ulang.
Constructor bernama dan factory constructor#
Sebuah kelas boleh memuat lebih dari satu constructor dengan nama berbeda. Ujian.dariSkalaEmpat menerima nilai skala 4 lalu mengonversinya ke skala 100 melalui daftar inisialisasi : this(...), yaitu mekanisme pemanggilan constructor lain sebelum tubuh constructor dijalankan. Constructor bernama lazim digunakan untuk kebutuhan konversi seperti ini, dan namanya membuat maksud pemanggilan terbaca tanpa komentar.
Factory constructor ditandai kata kunci factory dan boleh mengembalikan objek yang tidak harus baru dibuat. Pada Ujian.tercache, Map privat _cache menyimpan satu objek per mata pelajaran, dan putIfAbsent hanya membuat objek apabila kuncinya belum ada. Pemanggilan kedua dengan mata pelajaran sama mengembalikan objek pertama, sebagaimana dibuktikan identical(kimiaA, kimiaB) yang bernilai true. Pola ini adalah bentuk ringkas singleton per kunci, yakni pola yang menjamin hanya ada satu objek untuk satu kunci. Perbedaannya dengan constructor biasa, tubuh factory constructor tidak mengisi field secara langsung melainkan mengembalikan objek jadi, sehingga seluruh keputusan pembuatan objek ada pada factory constructor.
Getter dan metode#
Getter dideklarasikan dengan kata kunci get dan dibaca seperti field, tanpa tanda kurung. Getter lulus dihitung dari perbandingan nilai >= 75 setiap kali dibaca, sedangkan getter predikat menggunakan tubuh blok karena berisi beberapa percabangan. Getter paling tepat digunakan untuk nilai turunan yang selalu dapat dihitung ulang dari data yang ada, bukan untuk menyimpan hasil perhitungan yang mahal.
Metode tampilkan() menjalankan pekerjaan tertentu, yaitu mencetak ringkasan, tanpa mengembalikan nilai. Perbedaan praktisnya, getter dibaca sebagai properti pada interpolasi '$predikat', sedangkan metode dipanggil dengan tanda kurung seperti tampilkan(). Kelas pada Flutter juga memuat keduanya, dan metode build() yang menjadi inti setiap widget adalah contoh yang paling sering ditemui. Pemisahan ini menjaga field sebagai sumber data utama, sedangkan nilai turunannya dihitung hanya saat dibutuhkan.
Kesalahan umum#
- Memanggil getter dengan tanda kurung atau metode tanpa tanda kurung. Ekspresi
matematika.lulus()ditolak Dart karenalulusadalah getter, sedangkanmatematika.tampilkantanpa tanda kurung tidak menjalankan apa pun karena hanya berupa referensi metode. Perbaikannya, cocokkan bentuk pemanggilan dengan deklarasinya, yaitu getter dibaca polos dan metode dipanggil dengan(). - Mengisi field langsung di dalam tubuh factory constructor. Factory constructor tidak memiliki akses ke
this, sehingga penugasan ke field sepertimataPelajaran = ...di dalamnya ditolak saat kompilasi. Perbaikannya, buat objek melalui constructor lain di dalam factory, lalu kembalikan objek tersebut. - Mendeklarasikan field non-final untuk data yang seharusnya tetap. Field yang bebas diubah membuat isi objek sulit dipastikan karena bagian lain aplikasi dapat mengubahnya tanpa diketahui. Perbaikannya, nyatakan field
finaldan wujudkan perubahan data sebagai objek baru, bukan pengubahan objek lama.
Ringkasan#
- Constructor utama dengan
this.xmengisi field sekaligus mendeklarasikan parameternya, dan const constructor memungkinkan objek konstanta waktu kompilasi yang disatukan Dart menjadi satu objek. - Constructor bernama memberi jalur pembuatan alternatif, sedangkan factory constructor bebas mengembalikan objek dari cache atau yang sudah ada.
- Getter menghitung nilai turunan yang dibaca seperti field, sedangkan metode memuat perilaku yang dipanggil dengan tanda kurung.
- Field
finalmenjadikan objek immutable, danidentical()membandingkan identitas dua objek secara langsung.
Referensi#
- Classes — Dart — Dokumentasi resmi constructor, constructor bernama, factory constructor, getter, dan metode.
- Language — Dart — Halaman induk dokumentasi bahasa Dart yang memuat ringkasan seluruh fitur inti.