Birden Fazla Mixin Uygulama
Coddy'nin Lua Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 52 / 70.
Tek bir mixin, bir sınıfa tek bir davranış kümesi ekler. Ancak gerçek nesneler çoğu zaman birden fazla kaynaktan gelen yeteneklere ihtiyaç duyar. Bir oyun nesnesinin etrafta hareket etmesi ve ekranda görünür olması gerekebilir: aynı mixin’e ait olmayan iki ayrı sorumluluk.
Çözüm basittir: aynı sınıfa birden fazla mixin uygulayın. Her mixin kendi yöntemlerini sağlar ve sınıf sonunda bunların tümüne sahip olur:
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")
endHer iki mixin’i de öncekiyle aynı yardımcı işlevi kullanarak sınıfınıza uygulayın:
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)Artık GameObject örnekleri hem hareket edebilir hem de kendilerini görüntüleyebilir:
local obj = setmetatable({x = 0, y = 0}, GameObject)
obj:move(5, 3)
obj:show() -- 5, 3'te gösteriliyorBir uyarı: iki mixin aynı yöntem adını tanımlarsa, son uygulanan birincinin üzerine yazacaktır. Beklenmedik davranışlardan kaçınmak için mixin yöntemlerinizin adlarını farklı tutun.
Görev
KolayMixin'leri kullanarak birden fazla yeteneği birleştiren bir oyun için Character sınıfı oluşturalım! Karakteriniz hem düşmanlara saldırabilecek hem de kendini iyileştirebilecek: ayrı mixin'lerden gelen iki farklı davranış.
Kodunuzu dört dosyaya ayıracaksınız:
Attacker.lua::attack(targetName)metoduna sahip bir mixin oluşturun; bu metot{self.name} attacks {targetName} for {self.damage} damage!yazdırmalıdır (nesneninnamevedamagealanlarına sahip olduğunu varsayar).Healer.lua::heal(amount)metoduna sahip bir mixin oluşturun; bu metot amount değeriniself.healthdeğerine eklemeli ve{self.name} heals for {amount}. Health: {newHealth}yazdırmalıdır.Character.lua: Üç niteliğin tamamını saklayan:new(name, health, damage)kurucusuna sahip bir Character sınıfı oluşturun. Her karakterin saldırabilmesi ve iyileşebilmesi için hem Attacker hem de Healer mixin'lerini uygulayın.:status()yazdıran bir{name} - Health: {health}, Damage: {damage}metodu ekleyin.main.lua:applyMixinyardımcı fonksiyonunu burada yazın. Bir karakterin adını, sağlığını, hasarını, saldırılacak hedefi ve iyileştirme miktarını okuyun. Bir Character oluşturun, durumunu gösterin, hedefe saldırmasını sağlayın, kendini iyileştirmesini sağlayın ve ardından durumunu tekrar gösterin.
Beş girdi alacaksınız:
- Character adı (bir string)
- Başlangıç sağlığı (bir sayı)
- Hasar değeri (bir sayı)
- Saldırılacak hedefin adı (bir string)
- İyileştirme miktarı (bir sayı)
Çıktınız, karakterin her iki mixin yeteneğini de kullandığını göstermelidir:
{name} - Health: {health}, Damage: {damage}
{name} attacks {target} for {damage} damage!
{name} heals for {healAmount}. Health: {newHealth}
{name} - Health: {newHealth}, Damage: {damage}Örneğin girdiler Warrior, 100, 25, Goblin ve 30 ise çıktı şu şekilde olmalıdır:
Warrior - Health: 100, Damage: 25
Warrior attacks Goblin for 25 damage!
Warrior heals for 30. Health: 130
Warrior - Health: 130, Damage: 25Her mixin, Character sınıfına kendi metodunu sağlar. Karakter, mixin'lerin hiçbirinden miras almaz. Yalnızca applyMixin fonksiyonu aracılığıyla onların yeteneklerini kazanır. Birden fazla mixin'i birleştirmenin gücü budur!
Kendin dene
-- Ana dosya
-- TODO: applyMixin yardımcı fonksiyonunu yaz
-- Bu fonksiyon, bir mixin tablosundaki tüm metotları bir hedef tabloya kopyalamalıdır
local function applyMixin(target, mixin)
-- TODO: Mixin uygulamasını gerçekleştir
end
-- applyMixin'i global olarak kullanılabilir yap ki Character.lua onu kullanabilsin
_G.applyMixin = applyMixin
local Character = require('Character')
-- Girdileri oku
local name = io.read()
local health = tonumber(io.read())
local damage = tonumber(io.read())
local targetName = io.read()
local healAmount = tonumber(io.read())
-- TODO: Verilen name, health ve damage ile bir Character oluştur
-- TODO: Karakterin durumunu göster
-- TODO: Karakterin hedefe saldırmasını sağla
-- TODO: Karakterin kendini iyileştirmesini sağla
-- TODO: Karakterin durumunu tekrar göster
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1'Self' Kavramı
Fonksiyonlu TablolarAçık 'self'İki Nokta SözdizimiNokta vs İki NoktaÖzet - Hareket Eden Nokta4Proje: Dijital Banka
Proje KurulumuPara Yatırma Metodu7Çok Biçimlilik ve Geçersiz Kılma
Metotları Geçersiz KılmaÜst Sınıf Metotlarını ÇağırmaDuck TypingOrtak ArayüzTür KontrolüÖzet - Çalışan Rolleri2Sınıf Prototip Kalıbı
Prototip Kavramı__index ile Bağlama:new() KurucusuÖznitelikleri BaşlatmaBağımsız ÖrneklerÖzet - Araba Fabrikası5OOP'de Operatör Aşırı Yükleme
Nesneleri ToplamaNesneleri ÇıkarmaNesneleri BirleştirmeNesneleri Karşılaştırma (<, >)Özet - Cüzdan Matematiği8Kapsülleme
Adlandırma KurallarıGizlilik için Closure'larClosure'lar Aracılığıyla ErişimSalt Okunur TablolarDoğrulama MantığıÖzet - Güvenli Kasa11Tasarım Kalıpları (Lite)
Fabrika FonksiyonlarıSingleton TablosuIterator KalıbıObserver (Dinleyici)Özet - Logger Fabrikası3Nesne Durumu ve Davranışı
Örnek DeğişkenleriGetter MetotlarıSetter MetotlarıHesaplanmış ÖzelliklerString BiçimlendirmeEşitlik KontrolleriÖzet - Öğrenci Notu6Kalıtımın Temelleri
Kalıtım KurulumuMetot KalıtımıConstructor'ı GenişletmeAlt Sınıf Metotları EklemePaylaşılan ve BenzersizÖzet - Şekil Hiyerarşisi9Kompozisyon ve Mixin'ler
Has-A İlişkisiDelegasyonBasit Mixin'lerBirden Fazla Mixin UygulamaMixin'ler ve KalıtımÖzet - Robot BirleştirmeKendi başına pratik yap: Online Lua derleyicisi