Anwendung mehrerer Mixins
Teil des Abschnitts Objektorientierte Programmierung der Lua-Journey von Coddy. Lektion 52 von 70.
Ein einzelnes Mixin fügt einer Klasse einen Satz von Verhaltensweisen hinzu. Reale Objekte benötigen jedoch oft Fähigkeiten aus mehreren Quellen. Ein Spielobjekt muss sich möglicherweise bewegen und auf dem Bildschirm sichtbar sein: zwei getrennte Belange, die nicht in dasselbe Mixin gehören.
Die Lösung ist unkompliziert: Wende 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")
endWende beide Mixins mithilfe derselben Hilfsfunktion wie zuvor auf deine 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 anzeigen:
local obj = setmetatable({x = 0, y = 0}, GameObject)
obj:move(5, 3)
obj:show() -- Zeige bei 5, 3Ein Hinweis: Wenn zwei Mixins denselben Methodennamen definieren, überschreibt das zuletzt angewendete Mixin das zuerst angewendete. Halte deine Mixin-Methoden eindeutig, um unerwartetes Verhalten zu vermeiden.
Aufgabe
EinfachErstellen wir eine Character-Klasse für ein Spiel, die mithilfe von Mixins mehrere Fähigkeiten kombiniert! Deine Figur wird sowohl Gegner angreifen als auch sich selbst heilen können: zwei unterschiedliche Verhaltensweisen, die aus separaten Mixins stammen.
Du organisierst deinen Code über vier Dateien:
Attacker.lua: Erstelle ein Mixin mit einer:attack(targetName)-Methode, die{self.name} attacks {targetName} for {self.damage} damage!ausgibt (setzt voraus, dass das Objekt über die Feldernameunddamageverfügt)Healer.lua: Erstelle ein Mixin mit einer:heal(amount)-Methode, die den Betrag zuself.healthaddiert und{self.name} heals for {amount}. Health: {newHealth}ausgibtCharacter.lua: Erstelle eine Character-Klasse mit einem Konstruktor:new(name, health, damage), der alle drei Attribute speichert. Wende sowohl das Attacker- als auch das Healer-Mixin an, damit jede Figur angreifen und heilen kann. Füge eine:status()-Methode hinzu, die{name} - Health: {health}, Damage: {damage}ausgibtmain.lua: Schreibe hier die HilfsfunktionapplyMixin. Lies die Eingaben für den Namen, die Gesundheit und den Schaden einer Figur, ein Angriffsziel sowie einen Heilungsbetrag ein. Erstelle eine Character-Instanz, zeige ihren Status an, lasse sie das Ziel angreifen und sich selbst heilen und zeige anschließend erneut ihren Status an.
Du erhältst fünf Eingaben:
- Name der Figur (eine Zeichenkette)
- Ausgangsgesundheit (eine Zahl)
- Schadenswert (eine Zahl)
- Name des Angriffsziels (eine Zeichenkette)
- Heilungsbetrag (eine Zahl)
Deine Ausgabe sollte zeigen, wie die Figur beide Fähigkeiten der Mixins verwendet:
{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 lauten, sollte die Ausgabe folgendermaßen aussehen:
Warrior - Health: 100, Damage: 25
Warrior attacks Goblin for 25 damage!
Warrior heals for 30. Health: 130
Warrior - Health: 130, Damage: 25Jedes Mixin steuert seine eigene Methode zur Character-Klasse bei. Die Figur erbt von keinem der beiden Mixins. Sie erhält ihre Fähigkeiten einfach über die Funktion applyMixin. Das ist die Stärke der Kombination mehrerer Mixins!
Probier es selbst
-- Hauptdatei
-- TODO: Schreibe die applyMixin-Hilfsfunktion
-- Diese Funktion sollte alle Methoden von einer Mixin-Tabelle in eine Zieltabelle kopieren
local function applyMixin(target, mixin)
-- TODO: Implementiere die Mixin-Anwendung
end
-- Mache applyMixin global verfügbar, damit Character.lua es 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 Character mit dem gegebenen Namen, der Gesundheit und dem Schaden
-- TODO: Zeige den Status des Charakters
-- TODO: Lasse den Charakter das Ziel angreifen
-- TODO: Lasse den Charakter sich selbst heilen
-- TODO: Zeige den Status des Charakters erneut
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Das 'self'-Konzept
Tabellen mit FunktionenExplizites 'self'Die Doppelpunkt-SyntaxPunkt vs. DoppelpunktZusammenfassung – Beweglicher Punkt4Projekt: Digitale Bank
Projekt-SetupEinzahlungsmethode7Polymorphie & Überschreiben
Methoden überschreibenElternmethoden aufrufenDuck TypingGemeinsames InterfaceTyp prüfenRückblick - Mitarbeiterrollen10Projekt: Formen-Manager
Projekt-SetupRechteck-KlasseKreis-KlasseUmfang-MethodeFormen-SammlungGesamtflächeFormen filtern2Klassen-Prototyp-Muster
Das Prototyp-KonzeptVerknüpfung mit __indexDer :new()-KonstruktorAttribute initialisierenUnabhängige InstanzenZusammenfassung – Autofabrik5Operatorüberladung in OOP
Objekte addierenObjekte subtrahierenObjekte verkettenObjekte vergleichen (<, >)Rückblick – Wallet-Mathematik3Objektzustand und -verhalten
InstanzvariablenGetter-MethodenSetter-MethodenBerechnete EigenschaftenStrings formatierenGleichheitsprüfungenZusammenfassung – Studentennote6Grundlagen der Vererbung
Das Vererbungs-SetupMethoden vererbenDen Konstruktor erweiternChild-Methoden hinzufügenGemeinsam vs. EinzigartigZusammenfassung - Formen-Hierarchie9Komposition & Mixins
Has-A-BeziehungDelegationEinfache MixinsAnwendung mehrerer MixinsMixins vs. VererbungZusammenfassung – Roboter-Montage12Abschluss-Herausforderungen
Wiederholung - InventarsystemWiederholung - BenutzerverwaltungWiederholung - Score-TrackerFinaler OOP-CheckÜbe selbstständig: Online-Lua-Compiler