Menu
Coddy logo textTech

Einfache Mixins

Teil des Abschnitts Objektorientierte Programmierung der Lua-Journey von Coddy. Lektion 51 von 70.

Komposition ermöglicht es dir, Objekte in andere Objekte einzufügen. Aber was ist, wenn du Verhalten über nicht verwandte Klassen hinweg teilen möchtest?

Ein Player und ein MenuItem benötigen möglicherweise beide eine :describe()-Methode, aber sie haben keine gemeinsame übergeordnete Klasse. 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 hinüberkopierst:

local Printable = {}

function Printable:describe()
    print("Object: " .. tostring(self))
end

function Printable:log(message)
    print("[LOG] " .. message)
end

Um 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 dem Anwenden 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 erstellt

Im Gegensatz zur Vererbung erzeugen Mixins keine Eltern-Kind-Beziehung. Du kopierst einfach Funktionen von einer Tabelle in eine andere.

Dadurch eignen sich mixins ideal, um Hilfsfunktionen wie Protokollierung, Serialisierung oder Beschreibungsmethoden über Klassen hinweg gemeinsam zu nutzen, die ansonsten nichts gemeinsam haben.

challenge icon

Aufgabe

Einfach

Erstellen 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 zum Kategorisieren von Elementen, Beiträgen oder beliebigen Entitäten, die Beschriftungen benötigen.

Du organisierst deinen Code auf drei Dateien verteilt:

  • Taggable.lua: Erstelle eine Mixin-Tabelle mit zwei Methoden:
    • :addTag(tag): fügt einen Tag zu self.tags hinzu (setzt voraus, dass die Tabelle existiert)
    • :listTags(): gibt alle Tags im Format Tags: tag1, tag2, tag3 aus (oder Tags: none, wenn sie leer ist)
  • Article.lua: Erstelle eine Article-Klasse mit einem Konstruktor :new(title), der den Titel speichert und eine leere tags-Tabelle initialisiert. Wende das Taggable-Mixin an, um Article-Instanzen Tagging-Funktionen zu geben. Füge eine :getTitle()-Methode hinzu, die den Titel des Artikels zurückgibt.
  • main.lua: Schreibe hier die Hilfsfunktion applyMixin (du wirst sie in Article.lua über require verwenden). 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:

  1. Den Artikeltitel (eine Zeichenkette)
  2. Den ersten hinzuzufügenden Tag (eine Zeichenkette)
  3. Den zweiten hinzuzufügenden 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 wie folgt aussehen:

Title: Lua Basics
Tags: programming, tutorial

Denke daran: Die Mixin-Methoden funktionieren, weil Article-Instanzen über eine tags-Tabelle verfügen, auf der die Mixin-Methoden arbeiten können. Das Mixin erstellt diese Tabelle nicht. Das erledigt 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 applyMixin-Funktion
-- Diese Funktion sollte alle Methoden von einer mixin-Tabelle in eine target-Tabelle kopieren
function applyMixin(target, mixin)
    -- TODO: Durchlaufe das mixin und kopiere jede Methode nach target
end

-- Eingaben lesen
local title = io.read()
local tag1 = io.read()
local tag2 = io.read()

-- TODO: Erstelle ein Article mit dem gegebenen title

-- TODO: Füge beide Tags zum article hinzu

-- TODO: Gib den Titel im Format aus: Title: {title}

-- TODO: Liste alle Tags mit der listTags-Methode auf
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 Objektorientierte Programmierung

Übe selbstständig: Online-Lua-Compiler