Masukkan Password
65 6.14 What is Mixin in Dart OOP | Mixin in Dart Object Oriented Programming | Learn OOP | Dart Course
Materi ini membahas Mixin di Dart. Saya akan jelaskan dari konsep paling dasar, lalu masuk ke mixin, with, on, override, super, multiple mixin, sampai perbedaan mixin dengan inheritance (extends). Saya juga akan meluruskan beberapa istilah yang kemungkinan salah karena hasil transkrip suara, seperti βmiin/maginsβ β mixin, βDOTβ β Dart, dan βglassβ β class.
1. Apa itu Mixin?
Di materi ini, inti definisinya adalah:
Mixin adalah cara untuk menggunakan kembali (reuse) kode pada beberapa class tanpa menggunakan inheritance.
Jadi, bayangkan kita punya beberapa class:
Dog
Cat
Bird
Fish
Kemudian ternyata beberapa class tersebut membutuhkan kemampuan yang sama.
Misalnya:
Dog β bisa makan
Cat β bisa makan
Bird β bisa makan
Daripada kita menulis method eat() berkali-kali:
class Dog {
void eat() {
print('Animal is eating');
}
}
class Cat {
void eat() {
print('Animal is eating');
}
}
kita bisa membuat satu mixin:
mixin Animal {
void eat() {
print('Animal is eating');
}
}
Kemudian digunakan oleh class:
class Dog with Animal {
}
Sekarang Dog memiliki kemampuan eat().
var dog = Dog();
dog.eat();
Hasil:
Animal is eating
Jadi sederhananya:
Mixin = kumpulan kemampuan/perilaku yang bisa “ditempelkan” ke sebuah class.
Materi sumber menjelaskan mixin sebagai alat untuk reuse code dan composition, terutama ketika kita ingin berbagi behavior tanpa membuat hierarchy inheritance yang terlalu dalam.
2. Analogi Sederhana Mixin
Bayangkan kita mempunyai robot.
Robot bisa diberi berbagai kemampuan:
Robot
βββ bisa berjalan
βββ bisa berbicara
βββ bisa terbang
Kita bisa membuat kemampuan-kemampuan tersebut sebagai mixin:
mixin CanWalk {
void walk() {
print('Walking...');
}
}
mixin CanTalk {
void talk() {
print('Talking...');
}
}
mixin CanFly {
void fly() {
print('Flying...');
}
}
Kemudian:
class Robot with CanWalk, CanTalk, CanFly {
}
Robot sekarang mempunyai:
robot.walk();
robot.talk();
robot.fly();
Jadi mixin sangat cocok ketika kita ingin menggabungkan berbagai kemampuan ke sebuah class.
3. Cara Membuat Mixin
Untuk membuat mixin, kita menggunakan keyword:
mixin
Contoh:
mixin Animal {
void eat() {
print('Animal is eating');
}
}
Strukturnya mirip dengan class:
mixin NamaMixin {
// property
// method
}
Misalnya:
mixin Animal {
String name = 'Animal';
void eat() {
print('Animal is eating');
}
}
Mixin dapat mempunyai property/variable dan method.
4. Menggunakan Mixin dengan with
Nah, keyword paling penting ketika menggunakan mixin adalah:
with
Contohnya:
mixin Animal {
void eat() {
print('Animal is eating');
}
}
class Dog with Animal {
}
Perhatikan:
class Dog with Animal
Artinya:
Class
Dogmenggunakan kemampuan yang ada diAnimal.
Kemudian:
void main() {
var dog = Dog();
dog.eat();
}
Walaupun eat() tidak ditulis di dalam Dog, kita tetap bisa memanggil:
dog.eat();
Karena Dog menggunakan:
with Animal
Hasil:
Animal is eating
5. Mixin Bisa Memiliki Variable
Mixin bukan hanya berisi method.
Misalnya:
mixin Animal {
String name = 'Animal 1';
void eat() {
print('Animal is eating');
}
}
Kemudian:
class Dog with Animal {
}
Sekarang:
void main() {
var dog = Dog();
print(dog.name);
dog.eat();
}
Hasil:
Animal 1
Animal is eating
Jadi:
Animal
β
βββ name
βββ eat()
β
Dog with Animal
β
Dog mendapatkan name + eat()
Materi juga menunjukkan bahwa property dan function dari mixin dapat diakses melalui object class yang menggunakan mixin.
6. Apakah Mixin Sama dengan Inheritance?
Tidak sama.
Ini bagian yang sangat penting.
Inheritance menggunakan:
extends
Mixin menggunakan:
with
Contoh inheritance:
class Animal {
void eat() {
print('Animal is eating');
}
}
class Dog extends Animal {
}
Sedangkan mixin:
mixin Animal {
void eat() {
print('Animal is eating');
}
}
class Dog with Animal {
}
Sekilas terlihat mirip karena Dog bisa menggunakan eat().
Tetapi konsepnya berbeda.
extends
class Dog extends Animal
berarti:
Dog adalah turunan dari Animal.
Ada hubungan parent-child/inheritance.
with
class Dog with Animal
berarti:
Dog menggunakan kemampuan yang diberikan oleh mixin Animal.
Fokusnya adalah code reuse/composition, bukan hubungan parent-child.
7. Mixin Bisa Di-Override
Sama seperti method dari parent class, method dari mixin juga bisa kita override.
Misalnya:
mixin Animal {
void eat() {
print('Animal is eating');
}
}
Kemudian:
class Dog with Animal {
@override
void eat() {
print('Dog is eating');
}
}
Sekarang:
var dog = Dog();
dog.eat();
hasilnya:
Dog is eating
Kenapa?
Karena Dog mempunyai implementasi eat() sendiri.
Jadi ketika ada:
Dog.eat()
implementasi milik Dog yang digunakan.
8. Kenapa Menggunakan @override?
@override memberitahu Dart:
“Saya sedang mengganti/menimpa method yang sudah tersedia dari superclass atau mixin/interface.”
Contoh:
class Dog with Animal {
@override
void eat() {
print('Dog is eating');
}
}
@override sebenarnya bukan yang membuat override terjadi. Method tersebut tetap bisa menjadi override tanpa annotation dalam banyak kasus.
Tetapi sangat dianjurkan menggunakan:
@override
karena membantu kita dan analyzer Dart mendeteksi kesalahan.
9. Bagaimana Kalau Kita Masih Ingin Memanggil Method Mixin?
Nah, ini bagian menarik.
Misalnya:
mixin Animal {
void eat() {
print('Animal is eating');
}
}
Kemudian:
class Dog with Animal {
@override
void eat() {
print('Dog is eating');
super.eat();
}
}
Kemudian:
var dog = Dog();
dog.eat();
Hasil:
Dog is eating
Animal is eating
Kenapa?
Karena:
print('Dog is eating');
dijalankan terlebih dahulu.
Kemudian:
super.eat();
memanggil implementasi eat() dari bagian yang berada di bawah/menyediakan method tersebut dalam hierarchy mixin.
Jadi konsep sederhananya:
dog.eat()
β
Dog.eat()
β
print("Dog is eating")
β
super.eat()
β
Animal.eat()
β
print("Animal is eating")
Materi sumber juga mendemonstrasikan penggunaan super.eat() untuk memanggil implementasi eat() yang disediakan mixin.
10. Kalau super.eat() Dihapus?
Misalnya:
class Dog with Animal {
@override
void eat() {
print('Dog is eating');
}
}
Maka:
dog.eat();
hanya menghasilkan:
Dog is eating
Tidak ada:
Animal is eating
Karena kita sudah mengganti implementasi eat() milik mixin dan tidak memanggil implementasi sebelumnya.
11. Multiple Mixin
Ini salah satu kelebihan mixin yang sangat penting.
Kita bisa menggunakan lebih dari satu mixin pada sebuah class.
Misalnya:
mixin CanEat {
void eat() {
print('Eating');
}
}
mixin CanRun {
void run() {
print('Running');
}
}
Kemudian:
class Dog with CanEat, CanRun {
}
Perhatikan:
with CanEat, CanRun
Ada dua mixin.
Sekarang:
var dog = Dog();
dog.eat();
dog.run();
Bisa.
Hasil:
Eating
Running
Jadi:
CanEat
β
β
CanRun
β
β
Dog
Dog mendapatkan kemampuan dari keduanya.
Materi menekankan bahwa beberapa mixin dapat digunakan pada satu class dengan memisahkannya menggunakan koma.
12. Kenapa Multiple Mixin Berguna?
Misalnya kita punya:
Student
Teacher
Doctor
Athlete
Beberapa di antaranya bisa:
Student β bisa belajar
Teacher β bisa mengajar
Doctor β bisa mengobati
Athlete β bisa berlari
Tetapi kemampuan tersebut bisa saling overlap.
Misalnya:
Student β bisa berlari
Teacher β bisa berbicara
Doctor β bisa berbicara
Kita bisa membuat:
mixin CanRun {
void run() {
print('Running');
}
}
mixin CanTalk {
void talk() {
print('Talking');
}
}
Kemudian:
class Student with CanRun, CanTalk {
}
Sekarang Student punya:
student.run();
student.talk();
Kita tidak perlu membuat inheritance yang rumit.
13. Apa Maksud on pada Mixin?
Sekarang masuk ke bagian kedua dari materi.
Selain:
mixin Animal {
}
kita bisa menulis:
mixin Doctor on Person {
}
Contohnya:
abstract class Person {
}
mixin Doctor on Person {
void talking() {
print('Doctor is talking');
}
}
Perhatikan:
mixin Doctor on Person
on memberikan batasan.
Artinya:
Mixin
Doctorhanya boleh digunakan pada class yang merupakanPersonatau turunannya.
14. Contoh mixin ... on ...
Misalnya:
abstract class Person {
}
mixin Doctor on Person {
void talking() {
print('Doctor is talking');
}
}
Kemudian:
class Student extends Person with Doctor {
}
Ini boleh.
Kenapa?
Karena:
Student
β
extends Person
β
boleh menggunakan Doctor
Karena Doctor mensyaratkan:
on Person
Dan Student adalah turunan dari Person.
15. Kenapa on Person Dibutuhkan?
Bayangkan kita punya kemampuan khusus:
mixin Doctor on Person {
}
Kita ingin mengatakan:
“Kemampuan Doctor ini hanya boleh diberikan kepada Person.”
Jadi kita tidak ingin:
class Car with Doctor {
}
Karena:
Car bukan Person
Maka penggunaan tersebut akan ditolak oleh Dart.
Ini membuat mixin menjadi lebih aman dan terkontrol.
16. Contoh Lengkap
abstract class Person {
}
mixin Doctor on Person {
void talking() {
print('Doctor is talking');
}
}
class Student extends Person with Doctor {
}
void main() {
var student = Student();
student.talking();
}
Alurnya:
Person
β
β extends
Student
β
β with
β
Doctor
Ketika:
student.talking();
method tersebut berasal dari:
Doctor
meskipun Student sendiri kosong.
Hasil:
Doctor is talking
Materi memang menggunakan contoh Person, Doctor, dan Student untuk menunjukkan bahwa mixin yang dibatasi on Person dapat dipakai oleh subclass Person.
17. Kenapa Person2 Tidak Bisa?
Misalnya kita punya:
abstract class Person {
}
abstract class Person2 {
}
mixin Doctor on Person {
}
Kemudian:
class Student extends Person2 with Doctor {
}
Ini tidak diperbolehkan.
Kenapa?
Karena:
Doctor on Person
berarti Doctor membutuhkan Person.
Tetapi:
Student extends Person2
berarti Student adalah turunan dari:
Person2
bukan:
Person
Jadi persyaratannya tidak terpenuhi.
Sederhananya:
Doctor
β
harus digunakan pada Person
Student
β
adalah Person2
β tidak cocok
18. with vs on
Ini jangan sampai tertukar.
with
Digunakan ketika class memakai mixin:
class Dog with Animal {
}
Artinya:
Dog menggunakan Animal.
on
Digunakan ketika kita menentukan siapa yang boleh menggunakan mixin:
mixin Doctor on Person {
}
Artinya:
Doctor hanya bisa digunakan oleh Person atau turunannya.
Jadi gampangnya:
| Keyword | Fungsi |
|---|---|
with | menggunakan mixin |
on | membatasi class yang boleh menggunakan mixin |
extends | inheritance |
implements | memenuhi contract/interface |
19. Mixin Tidak Memiliki Constructor
Bagian terakhir materi mengatakan bahwa kita tidak membuat constructor di dalam mixin seperti constructor pada class.
Misalnya:
mixin Animal {
Animal() {
// ...
}
}
Materi menyatakan ini tidak diperbolehkan.
Yang perlu kita pahami secara konseptual adalah:
Mixin bukanlah class yang kita buat object-nya secara langsung.
Kita tidak melakukan:
var animal = Animal();
Mixin digunakan melalui sebuah class:
class Dog with Animal {
}
Kemudian kita membuat:
var dog = Dog();
Jadi yang dibuat object adalah:
Dog
bukan:
Animal
20. Mixin Tidak Dibuat Object Secara Langsung
Contoh:
mixin Animal {
void eat() {
print('Eating');
}
}
Kita tidak melakukan:
Animal animal = Animal();
Konsepnya bukan begitu.
Kita membuat:
class Dog with Animal {
}
lalu:
Dog dog = Dog();
Kemudian:
dog.eat();
Jadi:
Mixin
β
menyediakan behavior
β
Class menggunakan mixin
β
Object dibuat dari class
21. Mixin vs Abstract Class
Karena sebelumnya kamu sudah belajar abstraction, ini perbandingan yang penting.
Abstract class
Contoh:
abstract class Animal {
void eat();
void sleep() {
print('Sleeping');
}
}
Kemudian:
class Dog extends Animal {
@override
void eat() {
print('Dog is eating');
}
}
Fokusnya adalah:
membuat hubungan inheritance dan menyediakan abstraction/contract + kemungkinan implementasi bersama.
Mixin
mixin CanEat {
void eat() {
print('Eating');
}
}
class Dog with CanEat {
}
Fokusnya:
reuse behavior pada berbagai class.
22. Mixin vs extends
Ini juga wajib kamu pahami.
extends
class Dog extends Animal {
}
Artinya:
Dog adalah Animal
Ini hubungan inheritance.
with
class Dog with CanEat {
}
Artinya:
Dog memiliki kemampuan CanEat
Ini lebih seperti composition.
Analogi:
extends
"Dog adalah Animal"
with
"Dog diberi kemampuan CanEat"
23. Kenapa Mixin Bisa Menghindari Deep Inheritance?
Bayangkan kita membuat inheritance seperti ini:
Animal
β
Mammal
β
Pet
β
Dog
β
SmallDog
β
SpecialDog
Semakin lama hierarchy bisa semakin dalam.
Ini bisa membuat program sulit dipahami.
Dengan mixin, kita bisa membuat kemampuan terpisah:
CanRun
CanEat
CanSwim
CanFly
CanTalk
Kemudian:
class Dog with CanRun, CanEat {
}
dan:
class Bird with CanFly, CanEat {
}
serta:
class Fish with CanSwim, CanEat {
}
Tidak perlu membuat hierarchy panjang hanya untuk berbagi behavior.
24. Gambaran Besar Mixin
Kalau dirangkum secara visual:
MIXINS
β
βββββββββββΌββββββββββ
β β β
CanEat CanRun CanFly
β β β
ββββββ¬βββββ΄βββββ¬βββββ
β β
Dog Bird
Dog bisa:
class Dog with CanEat, CanRun {
}
Bird bisa:
class Bird with CanEat, CanFly {
}
Kita reuse kemampuan yang sama tanpa harus membuat semua class menjadi turunan satu sama lain.
25. Contoh Real-World: Sistem Kendaraan
Misalnya kita punya:
mixin CanDrive {
void drive() {
print('Driving');
}
}
mixin CanFly {
void fly() {
print('Flying');
}
}
mixin CanSwim {
void swim() {
print('Swimming');
}
}
Kemudian:
class Car with CanDrive {
}
class Airplane with CanDrive, CanFly {
}
class Boat with CanDrive, CanSwim {
}
Sekarang:
var car = Car();
car.drive();
Airplane:
var airplane = Airplane();
airplane.drive();
airplane.fly();
Boat:
var boat = Boat();
boat.drive();
boat.swim();
Kita bisa melihat betapa enaknya code reuse menggunakan mixin.
26. Bagaimana Kalau Dua Mixin Punya Method yang Sama?
Ini bagian yang belum dibahas mendalam dalam materi, tetapi penting untuk pemahaman.
Misalnya:
mixin A {
void hello() {
print('Hello from A');
}
}
mixin B {
void hello() {
print('Hello from B');
}
}
Kemudian:
class Test with A, B {
}
Ada dua hello().
Jika kita panggil:
var test = Test();
test.hello();
urutan mixin berpengaruh; mixin yang diaplikasikan paling akhir (B dalam contoh ini) menyediakan implementasi yang dipilih.
Jika ingin perilaku yang jelas, kita juga bisa override di class:
class Test with A, B {
@override
void hello() {
print('Hello from Test');
}
}
Maka implementasi Test yang digunakan.
27. Kesalahan Pemahaman yang Sering Terjadi
β Mixin adalah object
Bukan.
Mixin adalah mekanisme untuk menyediakan behavior.
β Mixin sama dengan inheritance
Tidak.
extends
= inheritance.
with
= menggunakan mixin.
β Mixin harus selalu menggunakan on
Tidak.
Kita bisa membuat:
mixin CanEat {
}
Tanpa on.
on digunakan ketika kita ingin membatasi penggunaan mixin.
β on berarti menggunakan mixin
Tidak.
Yang berarti menggunakan mixin adalah:
with
Sedangkan:
on
adalah restriction/constraint.
β @override hanya bisa digunakan untuk class parent
Tidak. Method yang disediakan oleh mixin juga dapat di-override.
28. Hubungan dengan Materi OOP yang Sudah Kamu Pelajari
Karena kamu sebelumnya sudah mempelajari beberapa konsep OOP Dart, sekarang kita bisa menghubungkannya:
Class
β
Object
β
Constructor
β
Encapsulation
β
Inheritance
β
Polymorphism
β
Abstract Class
β
Interface
β
Mixin
Mixin sebenarnya merupakan langkah lanjutan dari konsep code reuse.
Kalau inheritance mengatakan:
“Class B adalah turunan dari Class A.”
Mixin lebih mengatakan:
“Class B membutuhkan kemampuan yang disediakan oleh Mixin X.”
29. Contoh yang Menggabungkan Banyak Konsep
Mari kita buat contoh kecil:
abstract class Person {
String name;
Person(this.name);
}
mixin CanStudy {
void study() {
print('$name is studying');
}
}
mixin CanPlay {
void play() {
print('$name is playing');
}
}
class Student extends Person with CanStudy, CanPlay {
Student(String name) : super(name);
}
Kemudian:
void main() {
var student = Student('Budi');
student.study();
student.play();
}
Hasil:
Budi is studying
Budi is playing
Di sini banyak konsep bekerja sekaligus:
abstract class
abstract class Person
menyediakan konsep dasar Person.
extends
class Student extends Person
Student adalah turunan Person.
Constructor
Student(String name) : super(name);
Student meneruskan name ke constructor Person.
Mixin
with CanStudy, CanPlay
Student mendapatkan dua kemampuan tambahan.
Multiple mixin
with CanStudy, CanPlay
Student menggunakan lebih dari satu mixin.
30. Inti Materi yang Harus Kamu Ingat
Kalau untuk sekarang kamu ingin menghafal bagian terpentingnya saja, ingat 5 hal ini:
1. Membuat mixin
mixin Animal {
void eat() {
print('Eating');
}
}
2. Menggunakan mixin
class Dog with Animal {
}
3. Mixin bisa punya variable dan method
mixin Animal {
String name = 'Animal';
void eat() {
print('Eating');
}
}
4. Bisa menggunakan banyak mixin
class Dog with Animal, CanRun, CanSwim {
}
5. on membatasi siapa yang boleh menggunakan mixin
mixin Doctor on Person {
}
Artinya mixin Doctor hanya bisa digunakan oleh Person atau subclass-nya.
31. Ringkasan extends, implements, dan with
Karena ketiganya sekarang sudah kamu pelajari, tabel ini sangat penting:
| Keyword | Makna sederhana |
|---|---|
extends | “Saya adalah turunan dari class ini.” |
implements | “Saya berjanji memenuhi contract/interface ini.” |
with | “Saya mengambil/menggunakan behavior dari mixin ini.” |
on | “Mixin ini hanya boleh digunakan oleh class tertentu.” |
Contoh:
class Student extends Person
β Student adalah Person.
class Student implements Person
β Student memenuhi interface Person.
class Student with CanStudy
β Student mendapatkan behavior CanStudy.
Dan:
mixin Doctor on Person
β Doctor hanya boleh dipakai oleh Person atau turunannya.
π§ Cara paling gampang membayangkan Mixin
Bayangkan mixin = kemampuan tambahan.
Student
β
βββββββββββΌββββββββββ
β β β
CanStudy CanPlay CanRun
β β β
βββββββββββ΄ββββββββββ
Student tidak perlu menjadi turunan dari CanStudy, CanPlay, dan CanRun.
Dia cukup:
class Student with CanStudy, CanPlay, CanRun {
}
Jadi satu kalimat yang paling penting dari materi ini:
Mixin adalah mekanisme Dart untuk memakai ulang behavior/kode pada beberapa class dengan
with, tanpa harus membuat inheritance hierarchy yang panjang.