Menu
CoddyTech

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 bir davranış kümesi ekler. Ancak gerçek nesneler çoğu zaman birden fazla kaynaktan gelen yeteneklere ihtiyaç duyar. Bir oyun nesnesinin ekranda hareket etmesi ve görünür olması gerekebilir: aynı mixin'e ait olmayan iki ayrı sorumluluk.

Çözüm basittir: aynı sınıfa birden fazla mixin uygula. Her mixin kendi yöntemlerini ekler 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")
end

Öncekiyle aynı yardımcı işlevi kullanarak her iki karışımı da sınıfına uygula:

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 konumunda gösteriliyor

Bir uyarı: İki mixin aynı yöntem adını tanımlarsa, sonradan uygulanan ilkini geçersiz kılar. Beklenmedik davranışları önlemek için mixin yöntem adlarını farklı tut.

challenge icon

Görev

Kolay

Mixin'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: {self.name} attacks {targetName} for {self.damage} damage! çıktısını veren bir :attack(targetName) metoduna sahip bir mixin oluşturun (nesnenin name ve damage alanlarına sahip olduğunu varsayar)
  • Healer.lua: miktarı self.health değerine ekleyen ve {self.name} heals for {amount}. Health: {newHealth} çıktısını veren bir :heal(amount) metoduna sahip bir mixin oluşturun
  • Character.lua: Üç özelliğin tümünü saklayan :new(name, health, damage) kurucusuna sahip bir Character sınıfı oluşturun. Her karakterin saldırıp iyileşebilmesi için hem Attacker hem de Healer mixin'lerini uygulayın. {name} - Health: {health}, Damage: {damage} çıktısını veren bir :status() metodu ekleyin
  • main.lua: applyMixin yardımcı fonksiyonunu burada yazın. Bir karakterin adı, sağlığı ve hasar değeri, saldıracağı hedef ve iyileştirme miktarı için girdileri okuyun. Bir Character oluşturun, durumunu gösterin, hedefe saldırmasını sağlayın, kendini iyileştirin ve ardından durumunu tekrar gösterin.

Beş girdi alacaksınız:

  1. Karakter adı (bir dize)
  2. Başlangıç sağlığı (bir sayı)
  3. Hasar değeri (bir sayı)
  4. Saldırılacak hedefin adı (bir dize)
  5. İ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ı şö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: 25

Her mixin, Character sınıfına kendi metodunu ekler. Karakter iki mixin'den de kalıtım 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, mixin tablosundaki tüm metotları hedef tabloya kopyalamalıdır
local function applyMixin(target, mixin)
    -- TODO: mixin uygulamasını gerçekleştir
end

-- Character.lua dosyasının kullanabilmesi için applyMixin fonksiyonunu global olarak erişilebilir kıl
_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 ad, sağlık ve hasar değerleriyle 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
quiz iconKendini test et

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

Kendi başına pratik yap: Online Lua derleyicisi