Menerapkan Beberapa Mixins
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan Lua di Coddy. Pelajaran 52 dari 70.
Satu mixin menambahkan satu rangkaian perilaku ke class. Namun, object nyata sering membutuhkan kemampuan dari berbagai sumber. Sebuah object game mungkin perlu bergerak dan terlihat di layar: dua hal terpisah yang tidak seharusnya digabungkan dalam mixin yang sama.
Solusinya sederhana: terapkan beberapa mixin pada class yang sama. Setiap mixin menyumbangkan method-nya sendiri, dan class tersebut akhirnya memiliki semuanya:
local Movable = {}
function Movable:move(dx, dy)
self.x = self.x + dx
self.y = self.y + dy
end
local Visible = {}
function Visible:show()
print("Showing at " .. self.x .. ", " .. self.y)
end
function Visible:hide()
print("Hidden")
endTerapkan kedua mixin ke class-mu menggunakan fungsi helper yang sama seperti sebelumnya:
local function applyMixin(class, mixin)
for key, value in pairs(mixin) do
class[key] = value
end
end
local GameObject = {}
GameObject.__index = GameObject
applyMixin(GameObject, Movable)
applyMixin(GameObject, Visible)Sekarang, instance GameObject dapat bergerak dan menampilkan dirinya sendiri:
local obj = setmetatable({x = 0, y = 0}, GameObject)
obj:move(5, 3)
obj:show() -- Ditampilkan di 5, 3Satu hal yang perlu diperhatikan: jika dua mixin mendefinisikan nama method yang sama, mixin yang diterapkan kedua akan menimpa yang pertama. Gunakan nama method yang berbeda pada mixin-mixinmu untuk menghindari perilaku yang tidak terduga.
Tantangan
MudahMari buat class Character untuk game yang menggabungkan beberapa kemampuan menggunakan mixin! Karaktermu akan bisa menyerang musuh sekaligus memulihkan dirinya sendiri: dua perilaku berbeda yang berasal dari mixin terpisah.
Kamu akan menyusun kodemu dalam empat file:
Attacker.lua: Buat mixin dengan method:attack(targetName)yang mencetak{self.name} attacks {targetName} for {self.damage} damage!(mengasumsikan object memiliki fieldnamedandamage)Healer.lua: Buat mixin dengan method:heal(amount)yang menambahkan jumlah tersebut keself.healthdan mencetak{self.name} heals for {amount}. Health: {newHealth}Character.lua: Buat class Character dengan constructor:new(name, health, damage)yang menyimpan ketiga atribut. Terapkan mixin Attacker dan Healer agar setiap karakter bisa menyerang dan memulihkan diri. Sertakan method:status()yang mencetak{name} - Health: {health}, Damage: {damage}main.lua: Tulis fungsi pembantuapplyMixindi sini. Baca input untuk nama karakter, health, damage, target yang akan diserang, dan jumlah pemulihan. Buat Character, tampilkan statusnya, serang target, pulihkan diri, lalu tampilkan statusnya lagi.
Kamu akan menerima lima input:
- Nama karakter (sebuah string)
- Health awal (sebuah angka)
- Nilai damage (sebuah angka)
- Nama target yang akan diserang (sebuah string)
- Jumlah pemulihan (sebuah angka)
Output-mu harus menunjukkan karakter menggunakan kedua kemampuan mixin:
{name} - Health: {health}, Damage: {damage}
{name} attacks {target} for {damage} damage!
{name} heals for {healAmount}. Health: {newHealth}
{name} - Health: {newHealth}, Damage: {damage}Contohnya, jika input-nya adalah Warrior, 100, 25, Goblin, dan 30, output-nya adalah:
Warrior - Health: 100, Damage: 25
Warrior attacks Goblin for 25 damage!
Warrior heals for 30. Health: 130
Warrior - Health: 130, Damage: 25Setiap mixin menyumbangkan method-nya sendiri ke class Character. Karakter tidak mewarisi apa pun dari kedua mixin. Karakter hanya mendapatkan kemampuan tersebut melalui fungsi applyMixin. Inilah kekuatan menggabungkan beberapa mixin!
Coba sendiri
-- File utama
-- TODO: Tulis fungsi pembantu applyMixin
-- Fungsi ini harus menyalin semua method dari tabel mixin ke tabel target
local function applyMixin(target, mixin)
-- TODO: Terapkan mixin
end
-- Buat applyMixin tersedia secara global agar Character.lua dapat menggunakannya
_G.applyMixin = applyMixin
local Character = require('Character')
-- Baca input
local name = io.read()
local health = tonumber(io.read())
local damage = tonumber(io.read())
local targetName = io.read()
local healAmount = tonumber(io.read())
-- TODO: Buat Character dengan nama, kesehatan, dan kerusakan yang diberikan
-- TODO: Tampilkan status karakter
-- TODO: Buat karakter menyerang target
-- TODO: Buat karakter memulihkan kesehatannya sendiri
-- TODO: Tampilkan kembali status karakter
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Object
1Konsep "Self"
Tabel dengan Fungsi'self' EksplisitSintaks Titik DuaTitik vs Titik DuaRangkuman, Titik Bergerak4Proyek: Bank Digital
Penyiapan Proyekmethod Setoran7Polimorfisme & Overriding
Menimpa methodMemanggil method indukDuck TypingAntarmuka UmumMemeriksa TipeRingkasan: Peran Karyawan10Proyek: Pengelola Bentuk
Penyiapan Proyekclass Rectangleclass Circlemethod KelilingKumpulan BentukLuas TotalSaring Bentuk2Pola Prototype untuk class
Konsep PrototypeMenghubungkan dengan __indexKonstruktor :new()Menginisialisasi AtributInstans yang MandiriRangkuman: Pabrik Mobil5Pembebanan Operator dalam OOP
Menjumlahkan ObjekMengurangkan ObjekMenggabungkan ObjekMembandingkan Objek (<, >)Ulasan: Aritmetika Dompet8Enkapsulasi
Konvensi PenamaanClosure untuk PrivasiAkses melalui ClosureTabel Hanya-BacaLogika ValidasiRangkuman: Brankas Aman11Pola Desain (Ringan)
Fungsi FactoryTabel SingletonPola IteratorObserver (Listener)Rangkuman, Factory Logger3State dan Behavior pada object
Variabel InstansGetter methodSetter methodProperty TerhitungMemformat stringPemeriksaan KesetaraanRangkuman: Nilai Siswa6Dasar-Dasar Pewarisan
Menyiapkan PewarisanMewarisi methodMemperluas KonstruktorMenambahkan method untuk ChildSama vs UnikRangkuman: Hierarki Bentuk9Komposisi & Mixins
Hubungan Has-ADelegasiMixins SederhanaMenerapkan Beberapa MixinsMixins vs PewarisanRangkuman: Perakitan RobotLatihan sendiri: Compiler Lua online