Menu
Coddy logo textTech

Anwendung mehrerer Mixins

Teil des Abschnitts Object Oriented Programming der Lua-Journey von Coddy — Lektion 52 von 70.

Ein einzelnes Mixin fügt einer Klasse eine Reihe von Verhaltensweisen hinzu. Aber reale Objekte benötigen oft Fähigkeiten aus mehreren Quellen. Ein Spielobjekt muss sich möglicherweise bewegen und auf dem Bildschirm sichtbar sein – zwei separate Anliegen, die nicht in dasselbe Mixin gehören.

Die Lösung ist unkompliziert: Wenden Sie mehrere Mixins auf dieselbe Klasse an. Jedes Mixin steuert seine eigenen Methoden bei, und die Klasse verfügt am Ende über alle:

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

Wenden Sie beide Mixins mit derselben Hilfsfunktion von zuvor auf Ihre Klasse an:

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)

Jetzt können GameObject-Instanzen sich sowohl bewegen als auch selbst darstellen:

local obj = setmetatable({x = 0, y = 0}, GameObject)
obj:move(5, 3)
obj:show()  -- Anzeigen bei 5, 3

Ein Hinweis zur Vorsicht: Wenn zwei Mixins denselben Methodennamen definieren, überschreibt das zweite angewendete Mixin das erste. Halten Sie Ihre Mixin-Methoden eindeutig, um unerwartetes Verhalten zu vermeiden.

challenge icon

Aufgabe

Einfach

Lassen Sie uns eine Character-Klasse für ein Spiel erstellen, die mithilfe von Mixins mehrere Fähigkeiten kombiniert! Ihr Charakter wird in der Lage sein, sowohl Feinde anzugreifen als auch sich selbst zu heilen – zwei unterschiedliche Verhaltensweisen, die aus separaten Mixins stammen.

Sie werden Ihren Code über vier Dateien organisieren:

  • Attacker.lua: Erstellen Sie ein Mixin mit einer :attack(targetName)-Methode, die {self.name} attacks {targetName} for {self.damage} damage! ausgibt (setzt voraus, dass das Objekt die Felder name und damage besitzt).
  • Healer.lua: Erstellen Sie ein Mixin mit einer :heal(amount)-Methode, die den Betrag zu self.health addiert und {self.name} heals for {amount}. Health: {newHealth} ausgibt.
  • Character.lua: Erstellen Sie eine Character-Klasse mit einem Konstruktor :new(name, health, damage), der alle drei Attribute speichert. Wenden Sie sowohl das Attacker- als auch das Healer-Mixin an, damit jeder Charakter angreifen und heilen kann. Fügen Sie eine :status()-Methode hinzu, die {name} - Health: {health}, Damage: {damage} ausgibt.
  • main.lua: Schreiben Sie hier die Hilfsfunktion applyMixin. Lesen Sie Eingaben für den Namen eines Charakters, die Gesundheit, den Schaden, ein Ziel zum Angreifen und einen Heilungsbetrag ein. Erstellen Sie einen Character, zeigen Sie seinen Status an, lassen Sie ihn das Ziel angreifen, sich selbst heilen und zeigen Sie dann erneut seinen Status an.

Sie erhalten fünf Eingaben:

  1. Charaktername (ein String)
  2. Anfangsgesundheit (eine Zahl)
  3. Schadenswert (eine Zahl)
  4. Zielname zum Angreifen (ein String)
  5. Heilungsbetrag (eine Zahl)

Ihre Ausgabe sollte zeigen, wie der Charakter beide Mixin-Fähigkeiten nutzt:

{name} - Health: {health}, Damage: {damage}
{name} attacks {target} for {damage} damage!
{name} heals for {healAmount}. Health: {newHealth}
{name} - Health: {newHealth}, Damage: {damage}

Wenn die Eingaben beispielsweise Warrior, 100, 25, Goblin und 30 sind, sollte die Ausgabe wie folgt aussehen:

Warrior - Health: 100, Damage: 25
Warrior attacks Goblin for 25 damage!
Warrior heals for 30. Health: 130
Warrior - Health: 130, Damage: 25

Jedes Mixin steuert seine eigene Methode zur Character-Klasse bei. Der Charakter erbt nicht von einem der Mixins – er erhält seine Fähigkeiten einfach über die Funktion applyMixin. Das ist die Stärke der Kombination mehrerer Mixins!

Spickzettel

Mehrere Mixins können auf eine einzelne Klasse angewendet werden, um verschiedene Verhaltensweisen zu kombinieren. Jedes Mixin steuert seine eigenen Methoden zur Klasse bei.

Definieren Sie separate Mixins für verschiedene Belange:

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

Wenden Sie mehrere Mixins auf eine Klasse an, indem Sie die Hilfsfunktion applyMixin verwenden:

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)

Die Klasse verfügt nun über Methoden von allen angewendeten Mixins:

local obj = setmetatable({x = 0, y = 0}, GameObject)
obj:move(5, 3)
obj:show()  -- Zeigt an bei 5, 3

Wichtig: Wenn zwei Mixins denselben Methodennamen definieren, überschreibt das zweite angewendete Mixin das erste. Halten Sie Methodennamen über Mixins hinweg eindeutig, um Konflikte zu vermeiden.

Probier es selbst

-- Hauptdatei

-- TODO: Schreibe die Hilfsfunktion applyMixin
-- Diese Funktion sollte alle Methoden von einer Mixin-Tabelle in eine Ziel-Tabelle kopieren
local function applyMixin(target, mixin)
    -- TODO: Mixin-Anwendung implementieren
end

-- Mache applyMixin global verfügbar, damit Character.lua sie verwenden kann
_G.applyMixin = applyMixin

local Character = require('Character')

-- Eingaben lesen
local name = io.read()
local health = tonumber(io.read())
local damage = tonumber(io.read())
local targetName = io.read()
local healAmount = tonumber(io.read())

-- TODO: Erstelle einen Charakter mit dem angegebenen Namen, der Gesundheit und dem Schaden

-- TODO: Zeige den Status des Charakters an

-- TODO: Lasse den Charakter das Ziel angreifen

-- TODO: Lasse den Charakter sich selbst heilen

-- TODO: Zeige den Status des Charakters erneut an
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Object Oriented Programming