Apa itu kelas dan objek
Kelas adalah kategori atau pengelompokan. Kita mengabstraksi benda-benda di sekitar kita menjadi satu tipe yang seragam. Contohnya, semua manusia di dunia kita abstraksikan menjadi kelas «Manusia». Orang yang nyata seperti Bob atau Tom disebut objek.
Sebuah kelas berperan seperti «cetak biru» atau «template» yang mendefinisikan struktur dan perilaku semua objek yang terhubung dengannya.
Mari gunakan contoh kelas Manusia lagi: template ini menentukan apa yang dimiliki manusia dan apa yang bisa ia lakukan. Manusia memiliki nama, tangan, kaki dan organ tubuh lainnya; ia bisa berbicara dan berpikir. Data seperti nama atau umur adalah properti kelas, sedangkan tindakan seperti bicara atau berpikir adalah perilakunya. Singkatnya, kelas mengekstrak ciri umum dari benda nyata. Dengan template ini kita bisa membuat objek terpisah seperti Jack atau Jim.
Properti kelas (nama, umur) dan perilakunya (bicara, berpikir) masing-masing direpresentasikan dengan variabel dan fungsi.
Kelas mendefinisikan properti (variabel) dan metode (fungsi) yang harus dimiliki setiap objek.
Kelas bisa diibaratkan cetakan roti: cetakan itu sendiri bukan produk jadi. Dari satu cetakan bisa dibuat banyak roti nyata, sama seperti satu kelas bisa menghasilkan banyak objek.
Di awal sejarah pemrograman, konsep kelas belum ada. Bahasa C adalah contoh khas: hanya ada fungsi, variabel dan instruksi, model ini disebut pemrograman prosedural. Seiring perangkat lunak semakin kompleks, muncul banyak kekurangan paradigma ini: banyak kode duplikat, susunan tidak rapi, kurang hierarki dan keterbacaan. Kemudian muncul pendekatan baru: abstraksi logika program menjadi objek, mirip dengan dunia nyata. Kita bisa bandingkan dengan perusahaan: awalnya bos mengurus semua tugas sendiri. Setelah merekrut karyawan, urusan akuntansi diserahkan ke bagian keuangan dan rekrutmen ke bagian SDM. Pembagian tugas membuat alur kerja jauh lebih jelas.
Sebuah objek adalah instansi dari sebuah kelas.
Ketika kamu gunakan kata kunci new atau konstruktor, kelas akan menghasilkan satu objek baru.
Objek adalah entitas nyata saat program berjalan, mampu menyimpan data dan memanggil metode.
Hubungan antara kelas dan objek
- Kelas adalah cetak biru arsitektur; objek adalah rumah yang dibangun berdasarkan cetak biru tersebut.
- Dari satu kelas bisa dibuat banyak objek, setiap objek memiliki data mandiri masing-masing.
- Semua objek yang berasal dari kelas yang sama akan berbagi perilaku (metode) yang didefinisikan di dalam kelas.

Sekarang kita beralih ke bahasa Dart
Kita akan membahas poin-poin berikut
Dart adalah bahasa berorientasi objek penuh: setiap nilai adalah instansi kelas. Kecuali Null, semua kelas mewarisi kelas dasar Object.
Dart mengimplementasikan pewarisan dengan gabungan kelas dan Mixin
Pewarisan tunggal: setiap kelas hanya boleh memiliki satu induk kelas, namun Mixin memungkinkan penggunaan ulang beberapa blok logika dari kelas berbeda
Metode ekstensi: menambahkan fungsi baru ke kelas tanpa mengubah kode sumber atau membuat subkelas
Modifikator kelas: mengontrol apakah pustaka lain boleh mewarisi atau mengimplementasikan kelas ini
Mari mulai mempelajari kelas di Dart
Anggota kelas
Anggota kelas mencakup metode dan variabel: ini adalah elemen penyusun sebuah kelas.
Gunakan operator . untuk mengakses anggota instansi; operator aman null ?. mencegah pengecualian pointer null
Berikut contoh lengkap yang menunjukkan cara mendefinisikan kelas, membuat objek dari kelas, dan memanggil anggotanya melalui nama objek
// Mendefinisikan kelas, setara membuat cetakan
class Point {
double x, y;
Point(this.x, this.y);
// Metode instansi: hitung kuadrat jarak dua titik
double distanceTo(Point other) {
var dx = x - other.x;
var dy = y - other.y;
return dx * dx + dy * dy;
}
}
void main() {
// Buat objek p dari kelas Point untuk menjalankan operasi
var p = Point(2, 2);
// Baca variabel instansi (getter implisit)
print(p.y); //2.0
// Panggil metode instansi
double dist = p.distanceTo(Point(4, 4));
print(dist); // 8.0
// Akses aman dengan ?.
Point? nullablePoint;
var a = nullablePoint?.y; // Jika objek bernilai null, a akan menerima null tanpa error
print(a); // null
}Code language: JavaScript (javascript)

Konstruktor
Konstruktor standar
Dart berbeda dari bahasa sejenis C karena mendukung konstruktor bernama. Di sebagian besar bahasa turunan C, konstruktor harus memiliki nama yang sama dengan kelas, sedangkan Dart memungkinkan pembuatan konstruktor dengan identitas berbeda dari nama kelas.
Sintaks: NamaKelas() / NamaKelas.identitas() ;
Kata kunci new bersifat opsional (tersedia sejak Dart 2)
class Point {
double x, y; // Dua variabel anggota untuk menyimpan properti kelas
// Konstruktor standar: inisialisasi variabel x dan y
Point(this.x, this.y);
// Konstruktor bernama Point.fromJson: inisialisasi x dan y dari data JSON
Point.fromJson(Map<String, double> json)
: x = json['x']!,
y = json['y']!;
}
void main() {
var p1 = Point(2, 2);//Panggil konstruktor standar, kirim 2 dan 2 sehingga p1 memiliki x=2, y=2
var p2 = Point.fromJson({'x': 1, 'y': 2}); //Gunakan konstruktor bernama fromJson dengan data JSON
// Bisa tulis atau hapus new, perilakunya sama persis
var p3 = new Point(3, 3); //Buat objek lewat konstruktor standar
print("p1:(${p1.x},${p1.y}), p2:(${p2.x},${p2.y}), p3:(${p3.x},${p3.y})");
//Hasil output: p1:(2.0,2.0), p2:(1.0,2.0), p3:(3.0,3.0)
}Code language: JavaScript (javascript)
Konstruktor konstanta dengan const
Tambahkan kata kunci const di depan konstruktor untuk membuat objek konstanta waktu kompilasi; konstanta dengan parameter identik akan menggunakan instansi yang sama kembali.
class ImmutablePoint {
final double x, y;
// Aturan konstruktor konstanta: semua anggota harus diberi modifier final
const ImmutablePoint(this.x, this.y);
}
void main() {
// Buat instansi konstanta
var a = const ImmutablePoint(1, 1); // Kata kunci const wajib di sini
var b = const ImmutablePoint(1, 1);
print(identical(a, b)); // true, merujuk objek yang sama
var m = const ImmutablePoint(1, 1);
var n = const ImmutablePoint(2, 1);
print(identical(m, n)); // false, nilai berbeda menghasilkan objek terpisah
// Tanpa const: objek biasa, tidak berbagi instansi
var c = ImmutablePoint(1, 1);
print(identical(a, c)); //false
// Di dalam konteks const, const bagian dalam bisa dihilangkan
const pointMap = {
'p1': [ImmutablePoint(0, 0)],
'p2': [ImmutablePoint(1, 10), ImmutablePoint(-2, 11)]
};
print(pointMap); //{p1: [Instance of 'ImmutablePoint'], p2: [Instance of 'ImmutablePoint', Instance of 'ImmutablePoint']}
print(identical(p1, p2)); // false
print(identical(p2, p3)); // false
print(identical(p1, p3)); // false
}Code language: PHP (php)
Konstruktor konstanta hanya menggunakan ulang instansi jika semua parameter yang dikirimkan sama persis; satu parameter saja berbeda akan menghasilkan dua objek mandiri.
Mendapatkan tipe runtime objek dengan runtimeType
Dapatkan tipe saat program berjalan melalui objek.runtimeType; disarankan pakai operator pengecekan tipe is dibanding bandingkan pakai runtimeType
class Point {
double x, y;
Point(this.x, this.y);
// Metode instansi: hitung kuadrat jarak dua titik
double distanceTo(Point other) {
var dx = x - other.x;
var dy = y - other.y;
return dx * dx + dy * dy;
}
}
void main() {
var p = Point(2, 3);
print("Tipe p: ${p.runtimeType}"); // Point
// Cara yang disarankan dan stabil
if (p is Point) {
print("p adalah instansi dari Point");
}
// Tidak disarankan untuk kode produksi
if (p.runtimeType == Point) {
print("p adalah instansi dari Point ");
}
}Code language: JavaScript (javascript)
Variabel instansi Instance Variables
- Tipe nullable yang tidak diinisialisasi bernilai default
null; tipe non-nullable wajib diinisialisasi - Semua variabel instansi otomatis punya getter implisit; variabel non-final atau late final tanpa inisialisasi akan dibuatkan setter otomatis
- Ekspresi inisialisasi biasa variabel instansi tidak boleh akses this; variabel late diizinkan akses this saat inisialisasi
- Variabel instansi final hanya bisa diberi nilai sekali: saat deklarasi, lewat parameter konstruktor, atau di daftar inisialisasi konstruktor
Getter dan setter implisit
class Point {
double? x; // Nilai awal null, getter + setter dibuat otomatis
double? y;
double z = 0; // Diinisialisasi nol
}
void main() {
var point = Point();
point.x = 4; // Panggil setter implisit
assert(point.x == 4); // Panggil getter implisit
assert(point.y == null);
print(point.z); // 0
}
Code language: JavaScript (javascript)
Batasan akses this pada ekspresi inisialisasi
double globalX = 1.5;
class Point {
// Diizinkan: akses variabel global luar tanpa pakai this
double? x = globalX;
// Error kompilasi: inisialisasi standar tidak boleh pakai this
// double? y = this.x;
// Diizinkan: variabel late bisa merujuk this saat inisialisasi
late double? z = this.x;
// Diizinkan: sintaks gula this.x di parameter konstruktor bukan ekspresi inisialisasi
Point(this.x, this.y);
double? y;
}
void main() {
var p = Point(null, 5);
print(p.z); // null
}
Code language: JavaScript (javascript)
Tiga cara inisialisasi variabel instansi final
class ProfileMark {
// Cara 1: inisialisasi langsung saat deklarasi
final DateTime start = DateTime.now();
final String name;
// Cara 2: berikan nilai lewat parameter konstruktor
ProfileMark(this.name);
// Cara 3: berikan nilai di daftar inisialisasi konstruktor; konstruktor bernama unnamed isi string kosong ke name secara default
ProfileMark.unnamed() : name = '';
}
void main() {
var m1 = ProfileMark("user1");
var m2 = ProfileMark.unnamed();
print(m1.name);
print(m2.name);
}
Code language: PHP (php)
Antarmuka implisit Implicit interfaces
Setiap kelas Dart memiliki antarmuka implisit yang berisi semua anggota instansi publik milik kelas tersebut.
implements: implementasikan antarmuka, wajib tulis ulang semua metode antarmukaextends: warisi kelas induk untuk pakai ulang implementasinya- Variabel privat awalan
_xxxtidak terpampang di antarmuka
1 Implementasi satu antarmuka
class Person {
final String _name;
Person(this._name);
// Metode publik antarmuka
String greet(String who) => "Hello $who, I'm $_name";
}
// Implementasi antarmuka Person: wajib tulis ulang semua anggotanya
class Impostor implements Person {
String get _name => "";
@override
String greet(String who) => "Hi $who, guess who?";
}
String greetBob(Person p) => p.greet("Bob");
void main() {
print(greetBob(Person("Kathy")));
print(greetBob(Impostor()));
}
Code language: PHP (php)
Saat subkelas menulis ulang metode antarmuka induk, gunakan anotasi @override, mirip Java. Kata kunci implements dipakai untuk implementasi antarmuka.

2 Implementasi beberapa antarmuka sekaligus
// Kelas abstrak
abstract class Comparable {
int compareTo(Object other);
}
// Kelas abstrak
abstract class Location {
double get x;
double get y;
}
// Implementasi dua antarmuka secara bersamaan
class Point implements Comparable, Location {
@override
double x, y;
Point(this.x, this.y);
@override
int compareTo(Object other) {
if (other is Point) {
return (x + y).compareTo(other.x + other.y);
}
return -1;
}
}
void main() {
var p = Point(2, 3);
print(p.x);
print(p.compareTo(Point(1, 1)));
}
Code language: PHP (php)
@override
double x, y;
Anotasi ini berarti kedua properti ini menimpa getter abstrak yang didefinisikan di antarmuka induk Location.
Variabel statis & metode statis static
1. Variabel statis static (variabel kelas, unik secara global)
- Berada milik kelas itu sendiri, bukan milik instansi; inisialisasi tertunda: baru dibuat saat akses pertama kali
- Disarankan beri nama konstanta statis pakai camelCase huruf kecil
class Queue {
static const initialCapacity = 16; // Konstanta statis
static int count = 0; // Variabel statis yang bisa diubah
Queue() {
count++;
}
}
void main() {
assert(Queue.initialCapacity == 16); // Terinisialisasi saat diakses, nilai standar 16
Queue(); // Tambah count 1
Queue();
print(Queue.count); // 2
}
Code language: JavaScript (javascript)
2. Metode statis static (metode kelas)
- Tidak punya referensi
this, jadi tidak bisa akses anggota instansi; hanya boleh akses variabel statis - Dipanggil langsung pakai sintaks
NamaKelas.metode() - Bisa dikirim sebagai konstanta waktu kompilasi ke konstruktor konstanta
import 'dart:math';
class Point {
double x, y;
Point(this.x, this.y);
// Metode statis: hitung jarak lurus dua titik
static double distanceBetween(Point a, Point b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
}
void main() {
var a = Point(2, 2);
var b = Point(4, 4);
var dist = Point.distanceBetween(a, b);
print(dist); // sekitar 2,828
}Code language: JavaScript (javascript)

Metode statis milik kelas, jadi harus dipanggil lewat nama kelas dan kirim dua instansi Point sebagai parameter.