Inheritance (Jalur Nepo Baby) đ§Ŧ
Prinsip utama programmer adalah DRY (Don't Repeat Yourself). Jangan ngetik properti yang sama berkali-kali kalo Class lu bisa dapet warisan utuh dari Class bapaknya!
đ¯ Goals Hari Ini
- Memahami konsep dasar Inheritance (Pewarisan sifat).
- Bisa pakai keyword
extendsdansuper. - Bisa melakukan "pemberontakan" method pakai
@override. - Paham level tertinggi Arsitektur: Abstract Class.
â Cara Noob (Capek Ngetik)
Lu bikin game ada 3 role: Fighter, Mage, Marksman. Ketiganya butuh variabel nama, hp, dan fungsi jalan(). Lu ngetik variabel itu tiga kali di masing-masing Class.
class Mage { String nama; int hp; void jalan(){} }
class Marksman { String nama; int hp; void jalan(){} }
// Sinting! Kodenya ngulang terus!
â Cara Pro (Inheritance)
Lu bikin 1 Class Bapak (Hero) isinya nama, hp, jalan(). Terus si Fighter, Mage, dan Marksman tinggal di-set jadi anaknya (Mewarisi). Otomatis dapet semua skillnya!
class Fighter extends Hero { ... }
class Mage extends Hero { ... }
// Cerdas! Kodingan jadi pendek banget.
𩸠Keyword Extends & Super
Gimana cara ngoding jalur darah warisan di Dart dan menyetor data ke orang tua.
Bedah Tuntas: extends & super đ
extends Copy-Paste Gaib
Fungsi mutlaknya adalah mewariskan sifat. Saat lu ngetik class A extends B, komputer diem-diem nge-copy semua isi B dan nge-paste ke A.
Sistem akan mengakui bahwa: Zombie ADALAH SEBUAH Monster (IS-A Relationship).
super Remote Control Bapak
Kalo this menunjuk ke diri sendiri, super menunjuk ke Class Bapaknya. Punya 2 tugas utama:
super(x, y): Nyetor bahan baku ke Constructor Bapak.super.method(): Manggil skill/fungsi versi original milik Bapak.
class Monster {
String nama;
int hp;
Monster(this.nama, this.hp);
void jalan() => print("Jalan jalan...");
}
// 2. SANG ANAK 1
class Zombie extends Monster {
Zombie(String n, int h) : super(n, h); // Setor data
void gigit() => print("$nama menggigit!");
}
// 3. SANG ANAK 2
class Vampire extends Monster {
int bloodStock = 0;
Vampire(String n, int h) : super(n, h);
void terbang() => print("$nama terbang!");
}
đ§ AWAS KETUKER! (UML vs OOP)
Di mata kuliah RPL (Use Case Diagram), kalian pasti ketemu panah bertuliskan <<extend>>. Hati-hati, maknanya beda jauh!
- Di Kodingan (OOP):
extendsitu ya Inheritance (Pewarisan). - Di UML Use Case:
<<extend>>itu BUKAN pewarisan, melainkan Opsi Tambahan/Alternatif. (Contoh: Beli Barang -> di-extend -> Pakai Voucher). - Inheritance di UML: Namanya Generalization (Panah Segitiga Kosong). (Contoh: Actor User -> diturunkan jadi -> Admin).
đšī¸ Silsilah Visualizer
Klik Class di bawah untuk melihat isi jeroannya (Sifat Asli vs Sifat Warisan).
Membedah Tuntas: Kenapa Anak WAJIB Pake super()?
Hukum Mutlak Constructor di dalam Pewarisan.
Kalo Class Bapak punya Constructor yang MINTA DATA (misal butuh nama dan hp), maka si Anak yang menetas dari blueprint bapaknya itu WAJIB mencarikan data tersebut.
Analogi Setoran Pabrik:
Bapak adalah "Pabrik Pusat". Anak adalah "Cabang". Cabang harus minta data pembeli dari main(), lalu wajib disetor ke Pusat biar kerangkanya dirakit pakai perintah super().
class Monster {
String nama;
int hp;
Monster(this.nama, this.hp);
}
// 2. CABANG (Class Anak)
class Zombie extends Monster {
// Anak nerima data (n dan h), lalu DISETOR ke Bapak!
Zombie(String n, int h) : super(n, h);
void gigit() => print("$nama menggigit! đ§");
}
void main() {
// 3. RUANG EKSEKUSI
var z = Zombie("Zomblo", 150);
z.gigit();
print("HP si \${z.nama}: \${z.hp}");
}
đšī¸ Simulator Alur Setoran Data
Menunggu data...
Zombie(n, h) : super(n, h);
Monster(this.nama, this.hp);
âī¸ Pemberontakan (@override) & Super Method
Seringkali, Anak dapet warisan Method dari Bapaknya tapi dia mau modifikasi isinya.
Bahas Teori Bentar: Replace vs Enhance đ§
Kalo lu pake @override, lu punya DUA JALUR pilihan:
- Jalur Pemberontakan Murni (Replace): Bapaknya ngasih resep Nasi Goreng. Anaknya buang resep itu, diganti total jadi resep Seafood. Sifat asli Bapaknya hilang 100%.
- Jalur Damai (Enhance / Super): Bapaknya ngasih resep Nasi Goreng. Anaknya tetep masak pake resep itu (dipanggil pakai
super), TAPI di akhir ditambahin topping Keju Mozarella. Sifat bapaknya tetap jalan, ditambah kodenya si Anak!
1. Ganti Total (Replace)
Si anak nulis ulang kodenya dari nol. Kode asli bapaknya diabaikan.
void attack() => print("Mukul pake tangan kosong! đ");
}
class Fighter extends Hero {
@override
void attack() {
// Menghapus sifat bapak, diganti total:
print("TENDANGAN MAUT! đĨ");
}
}
2. Nambahin Topping (Enhance / Super)
Kode bapaknya tetap dijalankan dulu pakai super, baru ditambahin kode si Anak.
void attack() => print("Mukul pake tangan kosong! đ");
}
class Mage extends Hero {
@override
void attack() {
// 1. Panggil skill asli Bapaknya dulu
super.attack();
// 2. Tambahin topping skill Anak
print("Ditambah ledakan api BBOOOM! đĨ");
}
}
đšī¸ Test Override di Terminal
Lihat perbedaan output saat memanggil method .attack() jika diganti total (Replace) vs ditambahkan (Enhance).
đŗ Multi-Level Inheritance
Silsilah kakek, bapak, anak. Warisan sifat yang turun-temurun tak terputus!
Kode Lengkap Silsilah
Lihat bagaimana MobilSport di fungsi main() bisa mengeksekusi 3 fungsi berbeda yang diwariskan dari 3 generasi berbeda tanpa error!
class Kendaraan {
void jalan() => print("Mesin nyala...");
}
// 2. BAPAK
class Mobil extends Kendaraan {
void klakson() => print("TIN TIN!");
}
// 3. ANAK (Mewarisi Bapak & Kakek)
class MobilSport extends Mobil {
void turbo() => print("WUSSSHHHH!");
}
// RUANG EKSEKUSI
void main() {
var lambo = MobilSport();
lambo.jalan(); // Skill Kakek
lambo.klakson(); // Skill Bapak
lambo.turbo(); // Skill Sendiri
}
đšī¸ Test Drive Simulator
Kita telah mencetak sebuah objek: var lambo = MobilSport();
Coba panggil skill dan fungsi yang dimiliki objek tersebut!
đģ Abstract Class (Blueprint Wajib)
Kasta Tertinggi: Class gaib yang memaksa keturunannya mengikuti aturan.
Kenapa Butuh Abstract Class?
Terkadang, sebuah class induk bentuknya terlalu "umum", misal class Bentuk (Shape). Gimana cara ngitung luas "Bentuk"? Gak bisa kan? Yang bisa dihitung luasnya itu "Lingkaran" atau "Persegi" (Anak-anaknya).
- TIDAK BISA DICETAK JADI OBJECT: Lu gak bisa ketik
var b = Bentuk();. Pasti error! Dia murni 100% cuma cetakan/mandor. - Abstract Method: Fungsi yang namanya ada, tapi isinya (kurung kurawalnya
{}) GAK ADA. Artinya, mandor ini **memaksa** semua anaknya buat nulis isi fungsi itu. Kalo anaknya nolak, anaknya bakal kena Error!
đšī¸ Abstract Rules Enforcer
Dart Compiler SimulatorPilih Skenario Kode:
Compiler Output
Ngoding Time: Latihan Dasar đģ
Siapkan VS Code. Tiga skenario ini bakal membiasakan jari kalian menyambung-nyambungkan DNA Class.
Latihan 1: Super Method
Buat file latihan1.dart. Buktikan bahwa Anak bisa minta tolong bapaknya mengeksekusi sebagian fungsi.
class Handphone {
void nyalakan() => print("Ting! Layar menyala.");
}
class Smartphone extends Handphone {
@override
void nyalakan() {
super.nyalakan(); // Manggil fungsi bapak
print("Memuat OS Android... đ¤"); // Tambahan anak
}
}
void main() {
var hp = Smartphone();
hp.nyalakan();
}
Latihan 2: Hukum Abstract Class
Buat file latihan2_abstract.dart. Buktikan kalo Mandor memaksa anak nulis fungsinya.
abstract class Pekerja {
String nama;
Pekerja(this.nama);
// Abstract Method (Wajib diisi oleh anak)
void bekerja();
}
class Programmer extends Pekerja {
Programmer(String nama) : super(nama);
@override
void bekerja() {
print("$nama sedang mengetik kode Dart đ¨âđģ");
}
}
void main() {
var p1 = Programmer("Faker");
p1.bekerja();
}
Latihan 3: Multi-Level Silsilah đŗ
Buat file latihan3_multilevel.dart. Buktikan bahwa cucu mewarisi sifat dari kakeknya.
// 1. KAKEK
class Makhluk {
void bernafas() => print("Tarik nafas... đ¨");
}
// 2. BAPAK
class Hewan extends Makhluk {
void makan() => print("Nyam nyam... đ");
}
// 3. ANAK (Cucu dari Makhluk)
class Kucing extends Hewan {
void meow() => print("Meow meow! đą");
}
void main() {
var oyen = Kucing();
oyen.meow(); // Sifat Sendiri
oyen.makan(); // Warisan Bapak (Hewan)
oyen.bernafas(); // Warisan Kakek (Makhluk)
}
đ Final Boss Challenge: Sistem Absensi HRD
Ujian merakit Hierarchy Class yang kompleks! Gabungkan Abstract, Extends, Super Constructor, Override, dan Multi-Level Inheritance. Bikin file sistem_karyawan.dart.
Instruksi:
- Buat
abstract class Karyawan(nama, gajiBase, dan constructor). Didalamnya buat fungsi gantung:void hitungGaji();dan fungsi normalvoid absen(). - Buat class
Internextends Karyawan. OverridehitungGaji()print: gajiBase / 2. Terus overrideabsen()pake kombinasisuper.absen()dan print "Bawain kopi buat bos". - Buat class
Managerextends Karyawan. OverridehitungGaji()print: gajiBase + 5jt. - [NEW] Buat class
Direkturyang extends Manager (Multi-Level!). OverridehitungGaji()pakesuper.hitungGaji()ditambah print bonus 10jt. - Di
main(), bikin Intern, Manager, & Direktur lalu tes absen dan gaji mereka!
UML Diagram Result đ
Karyawan
hitungGaji()
absen() (super+)
hitungGaji()
hitungGaji() (super+)
// Kunci Jawaban Sistem HRD (Multi-Level & Abstract) đĸ
abstract class Karyawan { String nama; int gajiBase; Karyawan(this.nama, this.gajiBase); // Wajib dibikin sama anak void hitungGaji(); // Bawaan bapak void absen() { print("â $nama telah absen hadir! đ"); } } class Intern extends Karyawan { Intern(String n, int g) : super(n, g); @override void hitungGaji() { print("đ¸ Gaji Intern $nama: ${gajiBase ~/ 2} (Potongan magang)"); } @override void absen() { super.absen(); // Panggil fungsi absen Karyawan print(" âŗ Sambil bawain kopi buat bos â"); } } class Manager extends Karyawan { Manager(String n, int g) : super(n, g); @override void hitungGaji() { print("đ° Gaji Manager $nama: ${gajiBase + 5000000} (Plus Tunjangan)"); } } // MULTI-LEVEL: Direktur adalah turunan dari Manager! class Direktur extends Manager { Direktur(String n, int g) : super(n, g); @override void hitungGaji() { super.hitungGaji(); // Panggil hitungGaji() milik Manager print(" âŗ Ditambah bonus saham cair: 10000000 đ"); } } void main() { print("=== SISTEM KANTOR ===\n"); var magang = Intern("Joko", 10000000); magang.absen(); magang.hitungGaji(); print("\n------------------\n"); var bos = Manager("Pak Budi", 10000000); bos.absen(); bos.hitungGaji(); print("\n------------------\n"); // Direktur mewarisi Manager, yang mewarisi Karyawan! var dir = Direktur("Pak Elon", 10000000); dir.absen(); // Warisan dari Kakek (Karyawan) dir.hitungGaji(); // Gabungan hitungan Bapak (Manager) + Direktur }