Einfache Mixins
Teil des Abschnitts Objektorientierte Programmierung der Lua-Journey von Coddy. Lektion 51 von 70.
Mit Komposition kannst du Objekte in andere Objekte einfügen. Aber was, wenn du Verhalten zwischen nicht verwandten Klassen teilen möchtest?
Sowohl ein Player als auch ein MenuItem benötigen möglicherweise eine :describe()-Methode, aber sie haben keine gemeinsame Oberklasse. Hier kommen Mixins ins Spiel.
Ein Mixin ist einfach eine Tabelle, die Funktionen enthält. Du „mischst“ diese Funktionen in eine Klasse, indem du sie hineinkopierst:
local Printable = {}
function Printable:describe()
print("Object: " .. tostring(self))
end
function Printable:log(message)
print("[LOG] " .. message)
endUm dieses Mixin auf eine Klasse anzuwenden, kopierst du jede Funktion aus der Mixin-Tabelle 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) -- Jetzt hat Player :describe() und :log()Nach der Anwendung des Mixins kann jede Player-Instanz diese Methoden aufrufen, als wären sie direkt in der Klasse definiert:
local p = setmetatable({}, Player)
p:log("Player created") -- [LOG] Player erstelltIm Gegensatz zur Vererbung stellen Mixins keine Eltern-Kind-Beziehung her. Du kopierst einfach Funktionen von einer Tabelle in eine andere.
Dadurch eignen sich Mixins perfekt dazu, nützliche Verhaltensweisen wie Protokollierung, Serialisierung oder Beschreibungsmethoden zwischen Klassen zu teilen, die ansonsten nichts gemeinsam haben.
Aufgabe
EinfachErstellen wir ein Tagging-System mit Mixins! Du erstellst ein Taggable-Mixin, das auf jede Klasse angewendet werden kann und Objekten die Möglichkeit gibt, eine Sammlung von Tags zu verwalten – nützlich, um Elemente, Beiträge oder andere Objekte zu kategorisieren, die Beschriftungen benötigen.
Du organisierst deinen Code auf drei Dateien:
Taggable.lua: Erstelle eine Mixin-Tabelle mit zwei Methoden::addTag(tag): fügtself.tagsein Tag hinzu (setzt voraus, dass die Tabelle existiert):listTags(): gibt alle Tags im FormatTags: tag1, tag2, tag3aus (oderTags: none, falls die Tabelle leer ist)
Article.lua: Erstelle eine Article-Klasse mit einem Konstruktor:new(title), der den Titel speichert und eine leeretags-Tabelle initialisiert. Füge eine Methode:getTitle()hinzu, die den Titel des Artikels zurückgibt.main.lua: Schreibe hier die HilfsfunktionapplyMixinund wende dann das Mixin mitapplyMixin(Article, Taggable)an, damit Article-Instanzen Tags verwalten können. Lies anschließend die Eingaben für einen Artikeltitel und zwei Tags ein. Erstelle einen Article, füge ihm beide Tags hinzu, gib den Titel aus und liste alle Tags auf.
Du erhältst drei Eingaben:
- Den Artikeltitel (eine Zeichenkette)
- Das erste hinzuzufügende Tag (eine Zeichenkette)
- Das zweite hinzuzufügende Tag (eine Zeichenkette)
Deine Ausgabe sollte den Artikeltitel gefolgt von seinen Tags anzeigen:
Title: {title}
Tags: {tag1}, {tag2}Wenn die Eingaben beispielsweise Lua Basics, programming und tutorial lauten, sollte die Ausgabe folgendermaßen aussehen:
Title: Lua Basics
Tags: programming, tutorialDenk daran: Die Mixin-Methoden funktionieren, weil Article-Instanzen eine tags-Tabelle haben, mit der die Mixin-Methoden arbeiten können. Das Mixin erstellt diese Tabelle nicht. Das macht dein Article-Konstruktor. Das Mixin stellt lediglich das gemeinsame Verhalten bereit!
Probier es selbst
-- Hauptdatei für das Tagging-System
local Taggable = require('Taggable')
local Article = require('Article')
-- TODO: Implementiere die Funktion applyMixin
-- Diese Funktion soll alle Methoden aus einer Mixin-Tabelle in eine Zieltabelle kopieren
function applyMixin(target, mixin)
-- TODO: Durchlaufe mixin und kopiere jede Methode nach target
end
-- TODO: Wende das Mixin Taggable mit applyMixin auf Article an
-- Eingaben lesen
local title = io.read()
local tag1 = io.read()
local tag2 = io.read()
-- TODO: Erstelle einen Article mit dem angegebenen Titel
-- TODO: Füge dem Artikel beide Tags hinzu
-- TODO: Gib den Titel im Format Title: {title} aus
-- TODO: Liste alle Tags mit der Methode listTags auf
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