Birden Fazla Mixin Uygulama
Coddy'nin Lua Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 52 / 70.
Tek bir mixin, bir sınıfa bir dizi davranış ekler. Ancak gerçek nesneler genellikle birden fazla kaynaktan gelen yeteneklere ihtiyaç duyar. Bir oyun nesnesinin hareket etmesi ve ekranda görünür olması gerekebilir; bunlar aynı mixin'e ait olmayan iki ayrı konudur.
Çözüm basittir: aynı sınıfa birden fazla mixin uygulayın. Her bir mixin kendi metodlarını ekler ve sınıf bunların hepsine 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 daha önceki aynı yardımcı fonksiyonu 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üleyebilirler:
local obj = setmetatable({x = 0, y = 0}, GameObject)
obj:move(5, 3)
obj:show() -- 5, 3 konumunda gösteriliyorBir uyarı: Eğer iki mixin aynı metot adını tanımlarsa, uygulanan ikincisi ilkinin üzerine yazacaktır. Beklenmedik davranışlardan kaçınmak için mixin metotlarınızı birbirinden 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; bunlar ayrı mixin'lerden gelen iki farklı davranıştır.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
Attacker.lua:{self.name} attacks {targetName} for {self.damage} damage!yazdıran bir:attack(targetName)metoduna sahip bir mixin oluşturun (nesneninnamevedamagealanlarına sahip olduğunu varsayar)Healer.lua: Miktarıself.healthdeğerine ekleyen ve{self.name} heals for {amount}. Health: {newHealth}yazdıran bir:heal(amount)metoduna sahip bir mixin oluşturunCharacter.lua: Her üç özniteliği de saklayan bir:new(name, health, damage)yapıcı metoduna (constructor) 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.{name} - Health: {health}, Damage: {damage}yazdıran bir:status()metodu ekleyinmain.lua:applyMixinyardımcı fonksiyonunu buraya yazın. Bir karakterin adı, sağlığı, hasarı, saldırılacak bir hedef ve bir iyileşme miktarı için girdileri 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:
- Karakter adı (bir dize)
- Başlangıç sağlığı (bir sayı)
- Hasar değeri (bir sayı)
- Saldırılacak hedef adı (bir dize)
- İyileşme 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ı şöyle 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 katar. Karakter her iki mixin'den de miras almaz; sadece applyMixin fonksiyonu aracılığıyla onların yeteneklerini kazanır. Birden fazla mixin'i birleştirmenin gücü budur!
Kopya kağıdı
Farklı davranış kümelerini birleştirmek için tek bir sınıfa birden fazla mixin uygulanabilir. Her mixin, sınıfa kendi metotlarını katar.
Farklı ilgi alanları için ayrı mixin'ler tanımlayın:
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")
endapplyMixin yardımcı fonksiyonunu kullanarak bir sınıfa birden fazla mixin 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)Sınıf artık uygulanan tüm mixin'lerden gelen metotlara sahiptir:
local obj = setmetatable({x = 0, y = 0}, GameObject)
obj:move(5, 3)
obj:show() -- 5, 3 konumunda gösteriliyorÖnemli: Eğer iki mixin aynı metot adını tanımlarsa, uygulanan ikinci mixin ilkinin üzerine yazacaktır. Çakışmaları önlemek için mixin'ler genelinde metot adlarını farklı tutun.
Kendin dene
-- Ana dosya
-- YAPILACAK: applyMixin yardımcı fonksiyonunu yazın
-- Bu fonksiyon, bir mixin tablosundaki tüm metotları bir hedef tabloya kopyalamalıdır
local function applyMixin(target, mixin)
-- YAPILACAK: Mixin uygulamasını gerçekleştirin
end
-- Character.lua'nın kullanabilmesi için applyMixin'i küresel olarak erişilebilir yapın
_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())
-- YAPILACAK: Verilen isim, can ve hasar ile bir Karakter (Character) oluşturun
-- YAPILACAK: Karakterin durumunu gösterin
-- YAPILACAK: Karakterin hedefe saldırmasını sağlayın
-- YAPILACAK: Karakterin kendisini iyileştirmesini sağlayın
-- YAPILACAK: Karakterin durumunu tekrar gösterin
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming 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ştirme