Einfache Mixins
Teil des Abschnitts Object Oriented Programming der Lua-Journey von Coddy — Lektion 51 von 70.
Komposition ermöglicht es Ihnen, Objekte in andere Objekte einzufügen. Aber was ist, wenn Sie Verhalten über nicht miteinander verwandte Klassen hinweg teilen möchten?
Ein Player und ein MenuItem benötigen möglicherweise beide eine :describe()-Methode, aber sie teilen keine gemeinsame Elternklasse. Hier kommen Mixins ins Spiel.
Ein Mixin ist einfach eine Tabelle, die Funktionen enthält. Sie „mischen“ diese Funktionen in eine Klasse, indem Sie sie kopieren:
local Printable = {}
function Printable:describe()
print("Object: " .. tostring(self))
end
function Printable:log(message)
print("[LOG] " .. message)
endUm dieses Mixin auf eine Klasse anzuwenden, kopieren Sie jede Funktion aus der Mixin-Tabelle in die Klassen-Tabelle:
local function applyMixin(class, mixin)
for key, value in pairs(mixin) do
class[key] = value
end
end
local Player = {}
Player.__index = Player
applyMixin(Player, Printable) -- Jetzt hat Player :describe() und :log()Nach dem Anwenden des Mixins kann jede Player-Instanz diese Methoden aufrufen, als wären sie direkt in der Klasse definiert worden:
local p = setmetatable({}, Player)
p:log("Player created") -- [LOG] Spieler erstelltIm Gegensatz zur Vererbung erstellen Mixins keine Eltern-Kind-Beziehung. Sie kopieren lediglich Funktionen von einer Tabelle in eine andere.
Dies macht Mixins perfekt für das Teilen von Utility-Verhalten – wie Logging, Serialisierung oder Beschreibungs-Methoden – über Klassen hinweg, die ansonsten nichts gemeinsam haben.
Aufgabe
EinfachLassen Sie uns ein Tagging-System mit Mixins bauen! Sie werden ein Taggable-Mixin erstellen, das auf jede Klasse angewendet werden kann und Objekten die Fähigkeit verleiht, eine Sammlung von Tags zu verwalten – nützlich zum Kategorisieren von Elementen, Posts oder jeder Entität, die Labels benötigt.
Sie werden Ihren Code über drei Dateien organisieren:
Taggable.lua: Erstellen Sie eine Mixin-Tabelle, die zwei Methoden enthält::addTag(tag)— fügt ein Tag zuself.tagshinzu (setzt voraus, dass die Tabelle existiert):listTags()— gibt alle Tags im FormatTags: tag1, tag2, tag3aus (oderTags: none, wenn sie leer ist)
Article.lua: Erstellen Sie eine Article-Klasse mit einem Konstruktor:new(title), der den Titel speichert und eine leeretags-Tabelle initialisiert. Wenden Sie das Taggable-Mixin an, um Article-Instanzen Tagging-Fähigkeiten zu verleihen. Fügen Sie eine:getTitle()-Methode hinzu, die den Titel des Artikels zurückgibt.main.lua: Schreiben Sie hier die HilfsfunktionapplyMixin(Sie werden sie in Article.lua via require verwenden). Lesen Sie dann Eingaben für einen Artikeltitel und zwei Tags ein. Erstellen Sie einen Article, fügen Sie beide Tags hinzu, geben Sie den Titel aus und listen Sie alle Tags auf.
Sie erhalten drei Eingaben:
- Der Artikeltitel (ein String)
- Das erste hinzuzufügende Tag (ein String)
- Das zweite hinzuzufügende Tag (ein String)
Ihre Ausgabe sollte den Titel des Artikels gefolgt von seinen Tags anzeigen:
Title: {title}
Tags: {tag1}, {tag2}Wenn die Eingaben beispielsweise Lua Basics, programming und tutorial sind, sollte die Ausgabe wie folgt aussehen:
Title: Lua Basics
Tags: programming, tutorialDenken Sie daran: Die Mixin-Methoden funktionieren, weil Article-Instanzen eine tags-Tabelle haben, auf der die Mixin-Methoden operieren können. Das Mixin erstellt diese Tabelle nicht – das erledigt Ihr Article-Konstruktor. Das Mixin stellt lediglich das gemeinsame Verhalten bereit!
Spickzettel
Ein Mixin ist eine Tabelle, die Funktionen enthält, die über nicht verwandte Klassen hinweg geteilt werden können, ohne eine Eltern-Kind-Beziehung zu erstellen.
Um ein Mixin zu erstellen, definieren Sie eine Tabelle mit Methoden:
local Printable = {}
function Printable:describe()
print("Object: " .. tostring(self))
end
function Printable:log(message)
print("[LOG] " .. message)
endUm ein Mixin auf eine Klasse anzuwenden, kopieren Sie dessen Funktionen in die Klassentabelle:
local function applyMixin(class, mixin)
for key, value in pairs(mixin) do
class[key] = value
end
end
local Player = {}
Player.__index = Player
applyMixin(Player, Printable)Nach dem Anwenden des Mixins können Instanzen die Mixin-Methoden aufrufen:
local p = setmetatable({}, Player)
p:log("Player created") -- [LOG] Player createdMixins sind ideal, um Hilfsverhalten wie Logging, Serialisierung oder Tagging über Klassen hinweg zu teilen, die keine Vererbung teilen.
Probier es selbst
-- Hauptdatei für das Tagging-System
local Taggable = require('Taggable')
local Article = require('Article')
-- TODO: Implementiere die applyMixin-Funktion
-- Diese Funktion sollte alle Methoden von einer Mixin-Tabelle in eine Ziel-Tabelle kopieren
function applyMixin(target, mixin)
-- TODO: Durchlaufe das Mixin und kopiere jede Methode in das Ziel
end
-- Eingaben lesen
local title = io.read()
local tag1 = io.read()
local tag2 = io.read()
-- TODO: Erstelle einen Artikel mit dem angegebenen Titel
-- TODO: Füge beide Tags zum Artikel hinzu
-- TODO: Gib den Titel im Format aus: Title: {title}
-- TODO: Liste alle Tags mit der listTags-Methode auf
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
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-Klasse2Klassen-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