Encapsulation (Pembungkusan) đ
Kalian gak mau kan data HP Hero kalian tiba-tiba jadi minus? Atau saldo bank kalian tiba-tiba diganti hacker dari luar? Hari ini kita belajar nge-Gembok Data!
đ¯ Goals Hari Ini
- Memahami filosofi keamanan data (Encapsulation).
- Menggunakan underscore (
_) untuk menjadikan data Private. - Bisa membuat filter data menggunakan Getter dan Setter.
â Tanpa Gembok (Akses Bebas)
Ibarat mesin ATM kalian dibongkar brankasnya. Siapapun dari luar (di `main()`) bisa masukin tangannya, narik duit sesukanya, bahkan ngubah angka saldo jadi negatif.
// Hacker bisa lakuin ini! Sangat bahaya!
bankBudi.saldo = -99999;
â Pake Gembok (Encapsulation)
Brankas dikunci rapat. Kalian cuma boleh berinteraksi lewat Layar & Tombol ATM (Method). Mau narik duit? Validasi PIN dulu, validasi limit saldo dulu. Gak bisa asal tarik!
bankBudi._saldo = 9999; // ERROR! Private!
// Bisanya cuma lewat pintu/method resmi:
bankBudi.tarikUang(50000);
đĄī¸ Private Modifier (Underscore `_`)
Gimana cara ngunci datanya di Dart?
Sangat Gampang!
Beda sama Java yang repot harus ngetik `private String nama;`, di Dart kalian cuma perlu ngasih garis bawah (underscore `_`) tepat di depan nama variabelnya.
// Ini Public (Bebas)
String nama = "Budi";
// Ini PRIVATE (Kegembok!)
int _saldo = 10000;
}
Di bahasa Dart, sifat Private (`_`) ini akan benar-benar aktif (terkunci) jika Class dan fungsi
main() berada di FILE DART YANG BERBEDA. Kalo ditulis di dalam 1 file yang sama, variabelnya masih bisa ditembus (aturan ini disebut library-privacy).
đšī¸ Simulator Library Privacy
Buktikan sendiri kenapa di Dart, file class harus dipisah dari main() agar gemboknya sukses!
Console Output
đĒ Getter & Setter (Jembatan Resmi)
Gimana dong kalo kita beneran mau ngedit variabel yang di-private? Kita butuh Jembatan!
Bahas Teori Bentar: Apa itu Getter & Setter? đ§
Karena datanya udah kita gembok pake _ (contoh: _saldo), kita butuh "Jembatan Resmi" buat baca dan ngubah isinya. Jembatan itu namanya Getter dan Setter.
đ¤ "Kalo di 1 file bisa ditembus, Getter/Setter jadi percuma dong?"
- Best Practice: Di dunia nyata (Flutter), Class PASTI dipisah ke file yang berbeda. Jadi gemboknya dijamin 100% aktif.
- Kekuatan Utama Setter (Satpam Logic): Tujuan utama Setter BUKAN cuma ngubah data, tapi MEMVALIDASI data. Kalo lu ubah variabel langsung (
_hp = -999), gamenya bisa error. Tapi kalo lewat Setter, Setter bisa dikasih logikaIf-Elsebuat mikir "Eh, angkanya minus, stop di 0 aja!".
Getter dan Setter ini aslinya adalah Method (Fungsi) di dalam mesin. TAPI, saat dipanggil dari luar, mereka menyamar menjadi variabel biasa. Jadi, cara manggilnya TIDAK PAKE TANDA KURUNG
().
Getter (Layar Kaca buat Ngintip) đ
Pake keyword get. Fungsinya murni cuma buat ngasih izin baca / liat data, tapi gak ngasih izin buat ngubah. Cocok buat bikin Read-Only data.
int _saldo = 500;
// Pintu Kaca buat ngintip _saldo
int get cekSaldo {
return _saldo;
}
}
void main() {
Dompet dompet1 = Dompet(); // Bikin objeknya dulu
// Manggilnya BUKAN pake () !
print(dompet1.cekSaldo);
}
Setter (Pintu Satpam buat Ngubah) đŽââī¸
Pake keyword set. Ini satu-satunya pintu buat ngubah data. Di pintu ini lu bisa taro Satpam (logika if-else) buat nyegah inputan ngawur!
int _saldo = 500;
// Pintu Satpam
set setor(int uang) {
if (uang > 0) {
_saldo += uang; // Boleh masuk
print("Setor berhasil! Saldo: $_saldo");
} else {
print("Tolak! Duit ngawur.");
}
}
}
void main() {
Dompet dompet1 = Dompet();
// Ngirim duit pake = (Sama Dengan) !
dompet1.setor = 50000;
}
đŽ Validation Simulator (Sistem Darah Hero)
Simulasikan Hero kena pukulan dari Boss. Bandingkan efek mengubah data tanpa validasi vs menggunakan Setter ber-validasi!
Hero HP Bar
Ready...
Ngoding Time: Latihan Dasar đģ
Siapkan VS Code. Tiga skenario latihan untuk membiasakan merakit Pintu Getter & Setter.
Latihan 1: Validasi HP Hero (Cegah Minus)
Buat file latihan1_hero.dart.
class Hero {
String nama = "Arthur";
int _hp = 100; // Digembok!
// Getter buat liat HP
int get hp => _hp;
// Setter pas kena hit (Ada validasinya)
set kenaHit(int damage) {
_hp -= damage;
if (_hp < 0) {
_hp = 0; // Cegah HP minus tembus bumi
}
}
}
void main() {
Hero h1 = Hero();
h1.kenaHit = 9999; // Dihajar naga 9999 damage!
print("Sisa HP: ${h1.hp}"); // Mentok di 0
}
Latihan 2: Read-Only Property
Kita bikin `Getter` aja, gak usah bikin `Setter`. Jadi data `id` gak bakal bisa diganti seumur hidup! (Buat file latihan2_readonly.dart)
class Member {
final String _idMember; // Final = Set sekali doang di awal
String nama;
Member(this._idMember, this.nama);
// Cuma ada GETTER (Read-only)
String get id => _idMember;
}
void main() {
var m1 = Member("VIP-001", "Joko");
print("ID: ${m1.id}");
// m1.id = "HACKER"; // Kalo lu buka baris ini, bakal ERROR!
}
Latihan 3: Getter Konversi Data (Suhu)
Getter itu sebenernya fungsi! Jadi lu bisa naruh rumus matematika di dalamnya sblm dikeluarin. (Buat file latihan3_suhu.dart)
class Termometer {
double _celcius = 0.0;
set celcius(double val) => _celcius = val;
double get celcius => _celcius;
// Getter 2 (Mikir & Konversi Otomatis)
double get fahrenheit {
return (_celcius * 9 / 5) + 32;
}
}
void main() {
var t = Termometer();
t.celcius = 30.0; // Input Celcius
print("C: ${t.celcius}");
print("F: ${t.fahrenheit}"); // Udah jadi Fahrenheit otomatis!
}
Latihan 4: Real World - Sistem Gaji (Pisah File)
Mari kita simulasikan proyek asli! Bikin Dua File Terpisah buat ngebuktiin kalo variabel private (_) 100% aman dan gak bisa di-hack dari file luar.
// File 1: karyawan.dart
class Karyawan {
String nama;
int _gajiPokok = 0; // Digembok! đ
Karyawan(this.nama);
// Setter Validasi UMR
set gaji(int nominal) {
if (nominal < 3000000) {
print("Tolak! Gaji $nama di bawah UMR.");
} else {
_gajiPokok = nominal;
print("â
Gaji $nama berhasil di-set: $_gajiPokok");
}
}
// Getter
int get gaji => _gajiPokok;
}
// File 2: main.dart
import 'karyawan.dart'; // Wajib di-import!
void main() {
var staff = Karyawan("Joko");
// staff._gajiPokok = 5000; // â Kalo lu buka ini, ERROR PASTI!
// Bisanya cuma lewat Setter
staff.gaji = 1500000; // Ditolak UMR
staff.gaji = 4500000; // â
Berhasil
}
đĻ Final Challenge: Brankas ATM Ber-PIN (Pisah File!)
Ujian komprehensif Encapsulation sesungguhnya! Kali ini kita buat dengan standar industri (Dipisah jadi 2 file).
Instruksi:
- Buat file pertama bernama
akun_bank.dart. Isinya adalah classAkunBankdengan property private:_pemilik,_saldo, dan_pinbeserta Constructornya. - Di dalam class tersebut, buat Getter untuk
pemilik. - Buat Method
cekSaldo(int pinInput). Jika PIN cocok return print saldo, jika salah print "Akses Ditolak!". - Buat Method
tarikUang(int jumlah, int pinInput). Validasi PIN, baru validasi Saldo. - Buat file kedua bernama
main.dart. Lakukanimport 'akun_bank.dart';. - Di dalam
main(), bikin object akun lu. Lalu coba tarik uang dengan PIN salah, dan coba lagi dengan PIN bener!
đ§ ATM Simulator (PIN: 1234)
// Kunci Jawaban Final (ATM Encapsulation Beda File) đĻ
// File 1: akun_bank.dart
class AkunBank { String _pemilik; int _saldo; int _pin; // Constructor AkunBank(this._pemilik, this._saldo, this._pin); // Getter biasa String get pemilik => _pemilik; // Method Cek Saldo ber-PIN void cekSaldo(int pinInput) { if (pinInput == _pin) { print("đ° Saldo $_pemilik: $_saldo"); } else { print("â AKSES DITOLAK: PIN SALAH!"); } } // Method Tarik Uang ber-PIN & Validasi void tarikUang(int jumlah, int pinInput) { if (pinInput != _pin) { print("â GAGAL TARIK: PIN SALAH!"); return; // Berhentikan fungsi } if (jumlah > _saldo) { print("â GAGAL TARIK: Saldo tidak cukup!"); } else { _saldo -= jumlah; print("â Berhasil tarik $jumlah. Sisa saldo: $_saldo"); } } }
// File 2: main.dart
import 'akun_bank.dart'; // Hubungkan ke file cetakan! void main() { AkunBank akun1 = AkunBank("Faker", 100000, 123456); print("Nasabah: ${akun1.pemilik}"); // akun1._saldo = 99999; // â Hacker gak tembus karena udah beda file! // Percobaan 1 (Hacker coba tarik uang) akun1.tarikUang(50000, 000000); // Percobaan 2 (Tarik uang legal) akun1.tarikUang(50000, 123456); }