Kelas class

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

  1. Tipe nullable yang tidak diinisialisasi bernilai default null; tipe non-nullable wajib diinisialisasi
  2. Semua variabel instansi otomatis punya getter implisit; variabel non-final atau late final tanpa inisialisasi akan dibuatkan setter otomatis
  3. Ekspresi inisialisasi biasa variabel instansi tidak boleh akses this; variabel late diizinkan akses this saat inisialisasi
  4. 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 antarmuka
  • extends: warisi kelas induk untuk pakai ulang implementasinya
  • Variabel privat awalan _xxx tidak terpampang di antarmuka

1 Implementasi satu antarmuka

class Person {
  final String _name;
  Person(this._name);
  // Metode publik antarmuka
  String greet(String who) =&gt; "Hello $who, I'm $_name";
}

// Implementasi antarmuka Person: wajib tulis ulang semua anggotanya
class Impostor implements Person {
  String get _name =&gt; "";
  @override
  String greet(String who) =&gt; "Hi $who, guess who?";
}

String greetBob(Person p) =&gt; 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.

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *