Menu
CoddyTech

Mixins vs Pewarisan

Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan Lua di Coddy. Pelajaran 53 dari 70.

Kamu sudah mempelajari dua cara untuk berbagi perilaku: inheritance menciptakan hubungan "is-a" melalui rantai prototype, sedangkan mixins menyalin fungsi langsung ke dalam class. Namun, kapan kamu sebaiknya menggunakan masing-masing pendekatan?

Gunakan pewarisan saat object memiliki identitas mendasar yang sama. Bird adalah Animal. Masuk akal jika Bird mewarisi perilaku dasar hewan seperti :eat() atau :sleep(). Hubungan ini bersifat permanen dan menentukan hakikat object tersebut.

Gunakan mixins saat kamu ingin menambahkan kemampuan yang tidak menentukan identitas inti object.

Tidak semua burung bisa terbang: penguin dan burung unta adalah burung, tetapi mereka tidak terbang. Terbang adalah kemampuan, bukan sifat yang menentukan apakah sesuatu adalah burung. Mixin Flyable memungkinkan kamu menambahkan kemampuan terbang pada burung yang membutuhkannya, tanpa memaksakannya pada semua burung.

Kedua pendekatan ini bekerja dengan sangat baik bersama-sama:

-- Bird mewarisi Animal (hubungan is-a)
local Bird = {}
Bird.__index = Bird
setmetatable(Bird, {__index = Animal})

-- Flyable adalah kemampuan (mixin)
local Flyable = {}
function Flyable:fly()
    print(self.name .. " soars through the sky!")
end

-- Terapkan mixin hanya pada burung yang bisa terbang
applyMixin(Bird, Flyable)

Pola ini memberimu keunggulan dari kedua sisi: hierarki class yang jelas untuk identitas bersama, ditambah kemampuan fleksibel yang dapat dicampurkan sesuai kebutuhan.

challenge icon

Tantangan

Mudah

Mari buat ekosistem kecil berisi makhluk yang menunjukkan kapan sebaiknya menggunakan pewarisan dibandingkan mixin! Kamu akan membuat class dasar Animal, Bird yang mewarisinya, dan mixin Swimmable, karena meskipun semua burung adalah hewan, tidak semua burung bisa berenang.

Kamu akan mengatur kodemu dalam empat file:

  • Animal.lua: Buat class dasar Animal dengan konstruktor :new(name) yang menyimpan nama. Sertakan method :eat() yang mencetak {name} is eating. Ini mewakili identitas inti yang dimiliki semua hewan.
  • Swimmable.lua: Buat mixin dengan method :swim() yang mencetak {self.name} is swimming. Ini adalah kemampuan, tidak semua makhluk bisa berenang, jadi kemampuan ini sebaiknya tidak menjadi bagian dari rantai pewarisan.
  • Bird.lua: Buat class Bird yang mewarisi Animal. Konstruktor :new(name, canSwim) harus memanggil konstruktor induk dan menyimpan apakah burung ini bisa berenang. Terapkan mixin Swimmable ke class Bird. Sertakan method :chirp() yang mencetak {name} chirps!. Ini adalah perilaku khusus burung.
  • main.lua: Tulis fungsi helper applyMixin di sini. Baca input untuk nama burung dan apakah burung itu bisa berenang (yes atau no). Buat instance Bird, lalu tunjukkan kemampuannya: panggil :eat() (diwarisi dari Animal), panggil :chirp() (method milik Bird), dan panggil :swim() hanya jika burung itu bisa berenang.

Kamu akan menerima dua input:

  1. Nama burung (sebuah string)
  2. Apakah burung itu bisa berenang: yes atau no

Jika burung itu bisa berenang, output-mu harus seperti ini:

{name} is eating
{name} chirps!
{name} is swimming

Jika burung itu tidak bisa berenang, output-mu harus seperti ini:

{name} is eating
{name} chirps!

Misalnya, jika inputnya adalah Duck dan yes, output-nya harus seperti ini:

Duck is eating
Duck chirps!
Duck is swimming

Jika inputnya adalah Sparrow dan no, output-nya harus seperti ini:

Sparrow is eating
Sparrow chirps!

Tantangan ini menunjukkan perbedaan utamanya: Bird adalah seekor Animal (pewarisan), tetapi berenang adalah kemampuan opsional (mixin). Mixin diterapkan ke class, tetapi logika utama programmu menentukan apakah kemampuan itu digunakan berdasarkan kemampuan tiap burung!

Coba sendiri

-- main.lua: Titik awal, buat burung dan tunjukkan kemampuannya

-- Fungsi pembantu untuk menerapkan mixin ke class
local function applyMixin(class, mixin)
    -- TODO: Salin semua method dari mixin ke class
    
end

-- Terapkan mixin Swimmable ke Bird sebelum memuat Bird dengan require
-- Note: Kamu mungkin perlu menangani ini di Bird.lua atau di sini

local Bird = require('Bird')
local Swimmable = require('Swimmable')

-- Terapkan mixin ke class Bird
applyMixin(Bird, Swimmable)

-- Baca input
local name = io.read()
local canSwimInput = io.read()

-- TODO: Tentukan apakah burung dapat berenang berdasarkan input ("yes" atau "no")

-- TODO: Buat instance Bird dengan nama dan kemampuan berenang

-- TODO: Panggil eat(), diwarisi dari Animal

-- TODO: Panggil chirp(), method milik Bird sendiri

-- TODO: Panggil swim() hanya jika burung dapat berenang
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Object

Latihan sendiri: Compiler Lua online