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. Doch echte Objekte benötigen oft Fähigkeiten aus mehreren Quellen. Ein Spielobjekt muss sich möglicherweise bewegen und auf dem Bildschirm sichtbar sein: zwei getrennte Aspekte, die nicht in dasselbe Mixin gehören.
Die Lösung ist einfach: Wende mehrere Mixins auf dieselbe Klasse an. Jedes Mixin steuert seine eigenen Methoden bei, und die Klasse erhält sie am Ende 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 mit 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 sich GameObject-Instanzen bewegen und sich selbst anzeigen:
local obj = setmetatable({x = 0, y = 0}, GameObject)
obj:move(5, 3)
obj:show() -- Anzeige bei 5, 3Ein Hinweis: Wenn zwei Mixins denselben Methodennamen definieren, überschreibt das zuletzt angewendete den zuerst angewendeten. Verwende unterschiedliche Methoden in deinen Mixins, um unerwartetes Verhalten zu vermeiden.
Aufgabe
EinfachLass uns eine Character-Klasse für ein Spiel erstellen, die mithilfe von Mixins mehrere Fähigkeiten vereint! Dein Charakter kann sowohl Gegner angreifen als auch sich selbst heilen: 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 (vorausgesetzt, das Objekt hat die Feldernameunddamage).Healer.lua: Erstelle ein Mixin mit einer:heal(amount)-Methode, die den Betrag zuself.healthaddiert und{self.name} heals for {amount}. Health: {newHealth}ausgibt.Character.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 jeder Charakter angreifen und heilen kann. Füge eine:status()-Methode hinzu, die{name} - Health: {health}, Damage: {damage}ausgibt.main.lua: Schreibe hier die HilfsfunktionapplyMixin. Lies die Eingaben für den Namen, die Gesundheit und den Schaden eines Charakters, ein Angriffsziel und eine Heilungsmenge ein. Erstelle einen Character, zeige seinen Status an, lass ihn das Ziel angreifen und sich selbst heilen und zeige anschließend seinen Status erneut an.
Du erhältst fünf Eingaben:
- Name des Charakters (ein String)
- Anfangsgesundheit (eine Zahl)
- Schadenswert (eine Zahl)
- Name des Angriffsziels (ein String)
- Zu heilender Betrag (eine Zahl)
Deine Ausgabe sollte zeigen, wie der Charakter beide Mixin-Fähigkeiten einsetzt:
{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 zum Beispiel Warrior, 100, 25, Goblin und 30 lauten, sollte die Ausgabe so 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. Der Charakter erbt von keinem der beiden Mixins. Durch die Funktion applyMixin erhält er einfach deren Fähigkeiten. Das ist die Stärke der Kombination mehrerer Mixins!
Probier es selbst
-- Hauptdatei
-- TODO: Schreibe die Hilfsfunktion applyMixin
-- Diese Funktion soll alle Methoden aus einer Mixin-Tabelle in eine Zieltabelle kopieren
local function applyMixin(target, mixin)
-- TODO: Implementiere die Anwendung des Mixins
end
-- Mache applyMixin global verfügbar, damit Character.lua es verwenden kann
_G.applyMixin = applyMixin
local Character = require('Character')
-- Eingaben einlesen
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 angegebenen Namen, health und damage
-- TODO: Zeige den Status des Charakters an
-- TODO: Lass den Charakter das Ziel angreifen
-- TODO: Lass den Charakter sich selbst heilen
-- TODO: Zeige den Status des Charakters erneut an
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