Masukkan Password
48 Inheritance in Dart | Dart inheritance | Dart Tutorial #48
Materi ini membahas inheritance (pewarisan) dalam Dart/OOP, lalu dilanjutkan dengan hubungan antar-class: association, aggregation, dan composition.
Ada beberapa bagian transcript yang merupakan hasil speech-to-text dan ada juga beberapa penjelasan yang perlu diluruskan supaya sesuai dengan Dart modern. Saya akan jelaskan dari dasar dengan contoh yang mudah.
1. Apa itu Inheritance?
Inheritance adalah mekanisme ketika sebuah class memperoleh atau mewarisi kemampuan dari class lain.
Dalam Dart, inheritance menggunakan keyword:
extends
Bentuk sederhananya:
class Parent {
// anggota milik Parent
}
class Child extends Parent {
// anggota milik Child
}
Artinya:
ChildmewarisiParent.
Contoh:
class Animal {
void eat() {
print("Animal is eating");
}
}
class Cat extends Animal {
void meow() {
print("Meow");
}
}
Sekarang:
void main() {
Cat cat = Cat();
cat.eat();
cat.meow();
}
Output:
Animal is eating
Meow
Kenapa cat.eat() bisa dipanggil?
Karena:
class Cat extends Animal
Jadi Cat mendapatkan member yang diwariskan dari Animal.
2. Istilah-istilah dalam Inheritance
Ada beberapa istilah yang harus kamu hafalkan.
Misalnya:
class Animal {
}
class Cat extends Animal {
}
Maka:
Animal
Disebut:
- Superclass
- Parent class
- Base class
Cat
Disebut:
- Subclass
- Child class
- Derived class
Gambarnya secara konsep:
Animal
/ \
Cat Dog
Animal adalah superclass.
Cat dan Dog adalah subclass.
3. Kenapa menggunakan extends?
Misalnya kita punya:
class Animal {
String name = "Animal";
void eat() {
print("Eating");
}
void sleep() {
print("Sleeping");
}
}
Kemudian:
class Cat extends Animal {
void meow() {
print("Meow");
}
}
Cat mempunyai:
Milik sendiri
meow()
Dari Animal
name
eat()
sleep()
Jadi secara sederhana:
Cat
├── meow() ← milik Cat
├── name ← diwariskan Animal
├── eat() ← diwariskan Animal
└── sleep() ← diwariskan Animal
Ketika membuat:
Cat cat = Cat();
kita bisa:
cat.name;
cat.eat();
cat.sleep();
cat.meow();
4. Apakah semua yang ada di superclass diwariskan?
Transcript mengatakan:
semua member diwariskan kecuali constructor.
Untuk pemahaman dasar, ini arah yang benar, tetapi ada beberapa detail penting di Dart.
Constructor tidak diwariskan
Misalnya:
class Animal {
Animal(String name) {
print(name);
}
}
class Cat extends Animal {
}
Constructor Animal(String name) tidak menjadi constructor milik Cat.
Jadi kita tidak bisa melakukan:
Cat("Tom"); // ❌
hanya karena Animal punya constructor tersebut.
Subclass harus memiliki constructor sendiri dan menginisialisasi superclass sesuai kebutuhan.
Contoh:
class Animal {
final String name;
Animal(this.name);
}
class Cat extends Animal {
Cat(String name) : super(name);
}
Sekarang:
Cat cat = Cat("Tom");
print(cat.name);
Output:
Tom
Nanti konsep super(...) ini sangat penting ketika membahas inheritance lebih lanjut.
5. Bagaimana dengan private member?
Ini bagian yang sering membingungkan.
Dalam Dart, tanda _ membuat identifier menjadi private terhadap library, bukan sekadar private terhadap class.
Misalnya:
class Animal {
String name = "Tom";
int _age = 5;
}
_age bukan berarti:
“hanya bisa digunakan oleh Animal.”
Lebih tepat:
_agehanya bisa diakses dari library yang sama.
Jadi konsep visibility Dart sedikit berbeda dari Java/C++.
Untuk pemahaman awal, ingat saja:
name → public
_age → private pada level library
6. Inheritance menghasilkan hubungan “IS-A”
Ini konsep yang sangat penting.
Kalau:
class Animal {}
class Cat extends Animal {}
Maka kita bisa mengatakan:
Cat IS-A Animal
Dalam bahasa Indonesia:
Cat adalah Animal.
Contoh lain:
class Vehicle {}
class Car extends Vehicle {}
Berarti:
Car IS-A Vehicle.
Atau:
Car
↓
Vehicle
Ini berbeda dengan:
Car HAS-A Engine
Nanti kita akan masuk ke sini ketika membahas composition.
7. Contoh sederhana inheritance
Mari buat contoh yang lebih lengkap.
class Employee {
String name;
double salary;
Employee(this.name, this.salary);
void work() {
print("$name is working");
}
void showSalary() {
print("Salary: $salary");
}
}
class Manager extends Employee {
String department;
Manager(
String name,
double salary,
this.department,
) : super(name, salary);
void manage() {
print("$name is managing $department");
}
}
Kemudian:
void main() {
Manager manager = Manager(
"Budi",
10000000,
"IT",
);
print(manager.name);
print(manager.salary);
manager.work();
manager.showSalary();
manager.manage();
}
Output:
Budi
10000000.0
Budi is working
Salary: 10000000.0
Budi is managing IT
Perhatikan.
Manager hanya mendefinisikan:
department
manage()
Tetapi dia juga bisa menggunakan:
name
salary
work()
showSalary()
karena berasal dari Employee.
8. Kenapa tidak copy-paste saja?
Ini pertanyaan penting dari transcript.
Misalnya tanpa inheritance kita melakukan:
class Employee {
String name;
double salary;
void work() {}
}
Kemudian:
class Manager {
String name;
double salary;
void work() {}
String department;
}
Kita copy:
name
salary
work()
dari Employee ke Manager.
Awalnya terlihat mudah.
Tapi bayangkan kita punya:
Employee
Manager
Developer
Designer
Accountant
HR
Director
Supervisor
...
Kalau setiap class harus copy-paste:
name
salary
work()
...
akan muncul masalah.
9. Masalah copy-paste
Masalah 1 — Duplicate code
Kode yang sama ditulis berkali-kali.
Misalnya:
void work() {
print("Working");
}
ada di 10 class.
Ini disebut code duplication atau redundancy.
Masalah 2 — Sulit melakukan perubahan
Misalnya kita ingin mengubah:
void work() {
print("Employee is working");
}
menjadi:
void work() {
print("Employee is working professionally");
}
Kalau copy-paste, kita harus mengubahnya di banyak tempat.
Dengan inheritance:
class Employee {
void work() {
print("Employee is working professionally");
}
}
Class turunan bisa menggunakan implementasi tersebut.
10. Benefit inheritance
Transcript menyebut beberapa keuntungan.
1. Code reusability
Kode bisa digunakan kembali.
class Animal {
void eat() {
print("Eating");
}
}
class Cat extends Animal {}
class Dog extends Animal {}
Cat dan Dog bisa menggunakan:
eat()
tanpa menulis ulang.
2. Mengurangi redundancy
Daripada:
Cat → eat()
Dog → eat()
Cow → eat()
Horse → eat()
kita bisa:
Animal
|
+--- Cat
+--- Dog
+--- Cow
+--- Horse
eat() diletakkan di tempat yang umum, yaitu Animal.
3. Membentuk class hierarchy
Kita bisa menyusun class dalam struktur.
Contoh:
Animal
/ \
Mammal Bird
/ \ \
Cat Dog Eagle
Ini disebut class hierarchy.
11. Jenis-jenis Inheritance
Transcript membahas:
- Single inheritance
- Multilevel inheritance
- Hierarchical inheritance
- Multiple inheritance
Mari kita bahas satu per satu.
12. Single Inheritance
Ini yang paling sederhana.
Satu superclass memiliki satu subclass.
Parent
|
Child
Contoh:
class Animal {
void eat() {
print("Eating");
}
}
class Cat extends Animal {
void meow() {
print("Meow");
}
}
Hubungannya:
Animal
↓
Cat
Cat mewarisi Animal.
13. Contoh Single Inheritance di Flutter
Ini sangat penting karena kamu belajar Flutter.
Kamu sering melihat:
class MyWidget extends StatelessWidget {
}
Artinya:
StatelessWidget
↓
MyWidget
StatelessWidget adalah superclass.
MyWidget adalah subclass.
Contoh:
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
@override
Widget build(BuildContext context) {
return Text("Hello");
}
}
Jadi ketika membuat widget sendiri, kamu sering menggunakan inheritance.
14. Multilevel Inheritance
Multilevel berarti inheritance bertingkat.
Contohnya:
A
↓
B
↓
C
Misalnya:
class Person {
String name = "Budi";
void introduce() {
print("My name is $name");
}
}
class Doctor extends Person {
String hospital = "RS Sehat";
void treatPatient() {
print("Treating patient");
}
}
class Specialist extends Doctor {
String specialization = "Cardiology";
void specialistWork() {
print("Specialist work");
}
}
Sekarang:
Specialist specialist = Specialist();
Specialist bisa menggunakan:
specialization
dari dirinya sendiri.
Juga:
hospital
treatPatient()
dari Doctor.
Dan:
name
introduce()
dari Person.
Secara konsep:
Person
│
└── Doctor
│
└── Specialist
Jadi:
Specialist mendapatkan kemampuan dari Doctor dan juga inheritance chain di atasnya.
15. Cara membayangkannya
Bayangkan:
Person
↓
Doctor
↓
Cardiologist
Person:
name
age
eat()
sleep()
Doctor menambahkan:
degree
hospital
treatPatient()
Cardiologist menambahkan:
specialization
performHeartTreatment()
Maka Cardiologist secara konseptual memiliki:
name
age
eat()
sleep()
degree
hospital
treatPatient()
specialization
performHeartTreatment()
16. Hierarchical Inheritance
Hierarchical berarti:
satu superclass mempunyai beberapa subclass.
Bentuknya:
Animal
/ \
Cat Dog
Contoh:
class Animal {
void eat() {
print("Eating");
}
}
class Cat extends Animal {
void meow() {
print("Meow");
}
}
class Dog extends Animal {
void bark() {
print("Woof");
}
}
Sekarang:
Cat cat = Cat();
cat.eat();
cat.meow();
dan:
Dog dog = Dog();
dog.eat();
dog.bark();
Keduanya mendapatkan:
eat()
dari Animal.
Tetapi:
Cat → meow()
Dog → bark()
berbeda.
17. Contoh Shape dari transcript
Misalnya kita punya:
class Shape {
double d1 = 0;
double d2 = 0;
void setData(double d1, double d2) {
this.d1 = d1;
this.d2 = d2;
}
}
Kemudian:
class Rectangle extends Shape {
void area() {
print("Area of rectangle = ${d1 * d2}");
}
}
Dan:
class Triangle extends Shape {
void area() {
print("Area of triangle = ${0.5 * d1 * d2}");
}
}
Strukturnya:
Shape
/ \
Rectangle Triangle
Ini hierarchical inheritance.
Contoh penggunaan:
void main() {
Rectangle rectangle = Rectangle();
rectangle.setData(4, 5);
rectangle.area();
Triangle triangle = Triangle();
triangle.setData(20, 20);
triangle.area();
}
Output:
Area of rectangle = 20.0
Area of triangle = 200.0
18. Multiple Inheritance
Ini berbeda.
Multiple inheritance berarti satu class memiliki lebih dari satu superclass langsung.
Secara konsep:
A B
\ /
\ /
C
Artinya C ingin mewarisi A sekaligus B.
Contoh konsep:
class A {
void methodA() {}
}
class B {
void methodB() {}
}
// Tidak bisa:
class C extends A, B { } // ❌
Dart tidak mendukung multiple inheritance melalui extends.
Satu class hanya bisa:
extends satu class
secara langsung.
19. Lalu bagaimana kalau ingin kemampuan dari banyak sumber?
Di Dart ada konsep mixin.
Contoh:
mixin CanFly {
void fly() {
print("Flying");
}
}
mixin CanSwim {
void swim() {
print("Swimming");
}
}
class Duck with CanFly, CanSwim {
}
Sekarang:
void main() {
Duck duck = Duck();
duck.fly();
duck.swim();
}
Output:
Flying
Swimming
Jadi jangan berpikir:
Dart tidak bisa menggunakan kemampuan dari banyak sumber.
Yang tepat:
Dart tidak mendukung multiple inheritance melalui
extends, tetapi memiliki mixin untuk composition/reuse behavior.
20. Kenapa Dart tidak menggunakan multiple inheritance?
Salah satu masalah klasik adalah diamond problem.
Bayangkan:
A
/ \
B C
\ /
D
Misalnya A punya:
void hello() {
print("Hello from A");
}
Kemudian B dan C sama-sama memiliki method hello().
Ketika D memanggil:
d.hello();
pertanyaannya:
Harus menggunakan versi B atau versi C?
Inilah salah satu persoalan yang dapat muncul dalam multiple inheritance.
Dart memilih model inheritance yang lebih sederhana: satu superclass langsung melalui extends, dengan mekanisme lain seperti mixin untuk reuse behavior.
21. Sekarang masuk ke Class Relationship
Bagian ini sangat penting karena tidak semua hubungan antar-class adalah inheritance.
Ada dua kelompok besar yang perlu kamu bedakan:
IS-A
Menggunakan inheritance.
Cat IS-A Animal
HAS-A
Biasanya menggunakan object/member dari class lain.
Car HAS-A Engine
22. Association
Association adalah hubungan antara dua class yang tidak harus menggunakan inheritance.
Misalnya:
class MusicPlayer {
void play() {
print("Playing music");
}
}
class Car {
MusicPlayer player = MusicPlayer();
}
Car memiliki object MusicPlayer.
Kita bisa:
Car car = Car();
car.player.play();
Tidak ada:
class Car extends MusicPlayer
Jadi ini bukan inheritance.
Hubungannya adalah:
Car HAS-A MusicPlayer
atau secara umum:
Car berasosiasi dengan MusicPlayer.
23. Association vs Inheritance
Ini wajib dibedakan.
Inheritance
class Animal {}
class Cat extends Animal {}
Hubungan:
Cat IS-A Animal
Association
class Engine {}
class Car {
Engine engine = Engine();
}
Hubungan:
Car HAS-A Engine
Jadi:
IS-A → inheritance
HAS-A → association/composition/aggregation
24. Aggregation
Aggregation adalah salah satu bentuk association yang secara konsep menunjukkan hubungan lebih lemah.
Artinya:
object bagian masih dapat hidup secara independen dari object pemilik/containernya.
Contoh:
Car ----> MusicPlayer
MusicPlayer bisa ada tanpa Car.
Misalnya:
MusicPlayer player = MusicPlayer();
Car car = Car(player);
Kemudian secara konsep:
MusicPlayer
↑
|
Car
Jika Car dihancurkan/dihapus, MusicPlayer secara konsep masih bisa digunakan oleh bagian program lain.
Contoh:
class MusicPlayer {
void play() {
print("Playing music");
}
}
class Car {
final MusicPlayer musicPlayer;
Car(this.musicPlayer);
}
Penggunaan:
void main() {
MusicPlayer player = MusicPlayer();
Car car = Car(player);
player.play();
car.musicPlayer.play();
}
MusicPlayer dibuat di luar Car, kemudian diberikan kepada Car.
Ini cocok untuk menggambarkan aggregation.
25. Composition
Composition juga merupakan bentuk association, tetapi hubungan antara “whole” dan “part” lebih kuat.
Contoh klasik:
Car
|
└── Engine
Secara konseptual:
Car memiliki Engine sebagai bagian penting dari struktur Car.
Contoh:
class Engine {
void start() {
print("Engine started");
}
}
class Car {
final Engine engine = Engine();
void startCar() {
engine.start();
}
}
Di sini Car membuat dan memiliki Engine secara langsung.
Car car = Car();
car.startCar();
26. Kenapa disebut composition?
Karena sebuah object dibangun dari object-object lain.
Misalnya:
Car
├── Engine
├── MusicPlayer
├── Wheel
└── Battery
Car “tersusun dari” bagian-bagian tersebut.
Secara konsep:
Car HAS-A Engine
Car HAS-A Wheel
Car HAS-A Battery
Ini bukan:
Car IS-A Engine
Jadi tidak tepat menggunakan inheritance:
class Car extends Engine // ❌
Kalau relasinya adalah “memiliki”:
class Car {
Engine engine = Engine();
}
27. Perbedaan Aggregation dan Composition
Ini bagian yang sering membingungkan.
Kuncinya adalah lifecycle dan ownership.
Aggregation
Object bagian bisa hidup sendiri.
Car ───────> MusicPlayer
↑
|
bisa hidup sendiri
Contoh:
MusicPlayer player = MusicPlayer();
Car car = Car(player);
player dibuat di luar Car.
Composition
Object bagian sangat erat dengan object utama.
Car
|
└── Engine
Contoh:
class Car {
final Engine engine = Engine();
}
Car yang membuat Engine.
28. Analogi yang mudah
Bayangkan sebuah komputer.
Composition
Komputer mempunyai motherboard.
Computer
|
└── Motherboard
Motherboard merupakan bagian penting dari komputer.
Secara konsep kita bisa menyebut:
Computer HAS-A Motherboard.
Aggregation
Sekarang bayangkan komputer memiliki mouse.
Computer ----> Mouse
Mouse bisa dipakai oleh komputer lain.
Mouse bisa tetap hidup sebagai object tersendiri.
Jadi hubungan ownership-nya lebih lemah.
29. Tapi hati-hati dengan definisi Composition di Dart
Ada satu hal penting.
Transcript memberikan aturan:
Kalau object bisa hidup sendiri → aggregation Kalau object tidak bisa hidup sendiri → composition.
Ini berguna sebagai cara belajar, tetapi dalam pemrograman modern, batas aggregation/composition tidak selalu bisa ditentukan hanya dari apakah object secara teknis masih bisa hidup setelah parent dihapus.
Yang lebih penting adalah:
- siapa yang memiliki object,
- siapa yang membuat object,
- lifecycle-nya bagaimana,
- apakah bagian tersebut dianggap bagian internal dari keseluruhan.
Jadi jangan menganggap:
new Engine()di dalamCarotomatis secara bahasa Dart berarti composition.
Dart sendiri tidak memiliki keyword aggregation atau composition.
Ini adalah istilah desain/OOP untuk menjelaskan hubungan antar-object.
30. Diagram besar seluruh materi
Sekarang kita gabungkan semuanya.
Inheritance
Animal
/ \
Cat Dog
Hubungan:
Cat IS-A Animal
Dog IS-A Animal
Menggunakan:
extends
Association
Car -------- MusicPlayer
Hubungan:
Car HAS-A MusicPlayer
Tidak perlu extends.
Aggregation
Car --------> MusicPlayer
↑
bisa berdiri sendiri
Ownership lebih lemah.
Composition
Car
|
└── Engine
Ownership/lifecycle lebih erat.
31. Cara paling mudah membedakan IS-A dan HAS-A
Kalau bingung apakah harus menggunakan inheritance, coba baca kalimatnya.
Misalnya:
“A Cat is an Animal.”
Masuk akal?
Ya.
Berarti:
class Cat extends Animal
Sekarang:
“A Car is an Engine.”
Masuk akal?
Tidak.
Jadi jangan:
class Car extends Engine
Coba:
“A Car has an Engine.”
Masuk akal?
Ya.
Berarti:
class Car {
Engine engine = Engine();
}
Ini jauh lebih masuk akal.
32. Contoh gabungan
Kita bisa menggunakan inheritance dan composition sekaligus.
class Vehicle {
void move() {
print("Vehicle is moving");
}
}
class Engine {
void start() {
print("Engine started");
}
}
class Car extends Vehicle {
final Engine engine = Engine();
void startCar() {
engine.start();
move();
}
}
Di sini ada dua relationship.
Pertama:
class Car extends Vehicle
Berarti:
Car IS-A Vehicle
→ inheritance.
Kedua:
final Engine engine = Engine();
Berarti:
Car HAS-A Engine
→ composition secara desain.
Jadi satu class bisa memiliki beberapa jenis hubungan dengan class lain.
33. Hubungan ini penting sekali dalam Flutter
Flutter sendiri banyak menggunakan konsep inheritance dan composition.
Misalnya:
class MyPage extends StatelessWidget {
...
}
Ini:
MyPage IS-A StatelessWidget
→ inheritance.
Tetapi di dalam build():
return Scaffold(
appBar: AppBar(
title: Text("Hello"),
),
body: Column(
children: [
Text("Hello"),
Icon(Icons.home),
],
),
);
Di sini kita banyak menyusun object dari object lain.
Secara sederhana:
Scaffold
├── AppBar
│ └── Text
│
└── Column
├── Text
└── Icon
Ini menunjukkan betapa pentingnya konsep composition dalam Flutter:
UI dibangun dengan menyusun banyak widget menjadi widget yang lebih besar.
Jadi kalau kamu memahami:
IS-A
HAS-A
kamu akan lebih mudah memahami struktur Flutter.
34. Koreksi beberapa bagian transcript
Ada beberapa bagian yang sebaiknya kamu catat.
1. “All members are inherited”
Jangan mengartikannya terlalu harfiah.
Constructor tidak diwariskan sebagai constructor subclass, dan visibility/private member di Dart punya aturan library-level.
2. “Inheritance creates blood relationship”
Ini hanya analogi.
Istilah teknisnya:
IS-A relationship
3. “Multiple inheritance tidak bisa”
Lebih tepat:
Dart tidak mendukung multiple inheritance melalui
extends, yaitu satu class tidak dapat memiliki lebih dari satu superclass langsung.
Tetapi Dart memiliki:
mixin
untuk menggunakan behavior dari beberapa sumber.
4. “Association = object class A dibuat di dalam class B”
Tidak harus.
Association adalah konsep yang lebih umum: dua class memiliki hubungan.
Object/reference bisa diperoleh melalui constructor, parameter, field, dependency, dan sebagainya.
5. “Composition pasti kalau object tidak bisa hidup tanpa parent”
Ini adalah model pembelajaran yang bagus, tetapi bukan aturan bahasa Dart.
Aggregation/composition adalah konsep desain, bukan fitur syntax khusus Dart.
35. Cheat Sheet
Simpan tabel ini karena sangat berguna.
| Konsep | Artinya | Contoh |
|---|---|---|
| Inheritance | Mewarisi class | Cat extends Animal |
| Superclass | Class yang diwarisi | Animal |
| Subclass | Class yang mewarisi | Cat |
| IS-A | Hubungan inheritance | Cat IS-A Animal |
| Single | 1 parent → 1 child | A → B |
| Multilevel | inheritance bertingkat | A → B → C |
| Hierarchical | 1 parent → banyak child | A → B,C |
| Multiple | 1 child → banyak parent | ❌ via extends di Dart |
| Association | Hubungan antar-class | Car HAS-A Player |
| Aggregation | HAS-A, ownership lebih lemah | Car → MusicPlayer |
| Composition | HAS-A, ownership lebih erat | Car → Engine |
extends | Mewarisi superclass | class Cat extends Animal |
with | Menggunakan mixin | class Duck with CanFly |
36. Cara mengingat paling sederhana
Kalau kamu menemukan dua class, tanyakan:
Pertanyaan 1
Apakah A adalah B?
Kalau iya:
IS-A
↓
Inheritance
↓
extends
Contoh:
Cat adalah Animal
class Cat extends Animal {}
Pertanyaan 2
Apakah A memiliki B?
Kalau iya:
HAS-A
↓
Association
↓
Aggregation / Composition
Contoh:
Car memiliki Engine
class Car {
Engine engine = Engine();
}
Inti materi yang perlu benar-benar kamu kuasai
Kalau seluruh video ini diringkas menjadi satu peta:
OOP CLASS RELATIONSHIPS
│
┌────────────┴────────────┐
│ │
IS-A HAS-A
│ │
Inheritance Association
│ │
extends ┌─────┴─────┐
│ │ │
┌──────┼──────┐ Aggregation Composition
│ │ │
Single Multi- Hierarchical
level
Dan untuk Dart:
extends → inheritance
with → mixin
object → association/composition/aggregation
Kalimat paling penting untuk diingat:
Inheritance menjawab “A adalah B”, sedangkan association/composition menjawab “A memiliki B”.
Contoh:
Cat IS-A Animal
Car HAS-A Engine
Kalau kamu sudah benar-benar memahami perbedaan IS-A vs HAS-A, materi inheritance berikutnya seperti super, method overriding, abstract class, polymorphism, interface, dan mixin akan jauh lebih mudah.