0Pricing
Lua Academy · Lektion

Konstruktoren und new()

Schreiben Sie Konstruktorfunktionen, die Instanzen erstellen und initialisieren

Konstruktoren und new() ist eine kostenlose Lua Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Lua Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Lua Academy-Kurs umfasst insgesamt 4 Lektionen.

Verantwortung des Konstruktors

Ein Konstruktor erstellt und initialisiert eine Instanz. Er erhält Anfangswerte, validiert sie, setzt Standardwerte für fehlende Felder und gibt die neue Instanz zurück. Ein gut entworfener Konstruktor stellt sicher, dass jede Instanz in einem gültigen Zustand startet.

local Player = {}
Player.__index = Player

function Player.new(name, hp, mp)
  assert(type(name)=="string" and name~="","need name")
  return setmetatable({
    name = name,
    hp   = hp or 100,
    mp   = mp or 50,
    alive = true,
    items = {},
  }, Player)
end

local p = Player.new("Hero")
print(p.name, p.hp, p.mp)  -- Hero  100  50

Fluenter Konstruktor

Ein fluenter Konstruktor gibt aus Setter-Methoden self zurück und ermöglicht dadurch Method Chaining während der Konstruktion. Dies ist ein Builder-Pattern in Lua.

local Config = {}
Config.__index = Config

function Config.new()
  return setmetatable({_data={}}, Config)
end

function Config:set(k,v) self._data[k]=v; return self end
function Config:build() return self._data end

local cfg = Config.new()
  :set("host","localhost")
  :set("port",8080)
  :set("debug",true)
  :build()

print(cfg.host, cfg.port)

Kopierkonstruktor

Ein Kopierkonstruktor erstellt eine neue Instanz mit denselben Werten wie eine vorhandene Instanz. Wichtig: Verwenden Sie eine flache oder tiefe Kopie, je nachdem, ob verschachtelte Tabellen gemeinsam genutzt werden oder unabhängig sein sollen.

local function deepCopy(orig)
  if type(orig)~="table" then return orig end
  local copy = {}
  for k,v in pairs(orig) do copy[deepCopy(k)]=deepCopy(v) end
  return setmetatable(copy, getmetatable(orig))
end

local Item = {}
Item.__index = Item

function Item.new(name, stats)
  return setmetatable({name=name, stats=stats or {}}, Item)
end

function Item:clone()
  return deepCopy(self)
end

local sword = Item.new("Sword",{damage=50})
local clone = sword:clone()
clone.stats.damage = 30
print(sword.stats.damage)  -- 50 (unchanged)

Konstruktor mit Validierung

Validieren Sie Konstruktorparameter immer. Lösen Sie bei ungültigen Eingaben aussagekräftige Fehler auf Ebene 2 aus (der Aufrufer ist verantwortlich). Dadurch werden Fehler früh erkannt und hilfreiche Fehlermeldungen erzeugt.

local Rectangle = {}
Rectangle.__index = Rectangle

function Rectangle.new(w, h)
  assert(type(w)=="number" and w>0,"width must be positive number")
  assert(type(h)=="number" and h>0,"height must be positive number")
  return setmetatable({width=w, height=h}, Rectangle)
end

function Rectangle:area() return self.width * self.height end
function Rectangle:perimeter() return 2*(self.width+self.height) end

local r = Rectangle.new(5, 3)
print(r:area(), r:perimeter())  -- 15  16

Muster für Standardwerte

Verwenden Sie eine Defaults-Tabelle, um optionale Konstruktorparameter übersichtlich zu behandeln. Dadurch vermeiden Sie lange Ketten aus x = x or default und machen Standardwerte explizit und leicht änderbar.

local Sprite = {}
Sprite.__index = Sprite

local DEFAULTS = {x=0,y=0,rotation=0,scale=1,visible=true,alpha=1}

function Sprite.new(image, opts)
  local cfg = opts or {}
  local self = {image=image}
  for k,v in pairs(DEFAULTS) do
    self[k] = cfg[k] ~= nil and cfg[k] or v
  end
  return setmetatable(self, Sprite)
end

local s = Sprite.new("hero.png",{x=100,y=200})
print(s.x,s.y,s.scale)  -- 100 200 1

Statische Factory-Methoden

Eine Klasse kann mehrere Factory-Methoden für unterschiedliche Erzeugungsszenarien besitzen. Das ist übersichtlicher, als einen einzelnen Konstruktor mit vielen optionalen Parametern zu überladen.

local Color = {}
Color.__index = Color

function Color.fromRGB(r,g,b)
  return setmetatable({r=r,g=g,b=b}, Color)
end

function Color.fromHex(hex)
  hex = hex:gsub("#","")
  return setmetatable({
    r=tonumber(hex:sub(1,2),16),
    g=tonumber(hex:sub(3,4),16),
    b=tonumber(hex:sub(5,6),16),
  }, Color)
end

function Color:toHex()
  return string.format("#%02X%02X%02X",self.r,self.g,self.b)
end

local red = Color.fromHex("#FF0000")
print(red:toHex())  -- #FF0000

Konstruktor-Registry

Verwenden Sie eine Registry, um alle Instanzen zu verfolgen. Dadurch werden globale Operationen wie „alle zerstören“ oder das Iterieren über alle Objekte eines Typs möglich.

local Enemy = {}
Enemy.__index = Enemy
Enemy._all = {}

function Enemy.new(name, hp)
  local self = setmetatable({name=name, hp=hp}, Enemy)
  Enemy._all[#Enemy._all+1] = self
  return self
end

function Enemy.destroyAll()
  for _, e in ipairs(Enemy._all) do
    print("Destroying:", e.name)
  end
  Enemy._all = {}
end

Enemy.new("Goblin",30)
Enemy.new("Orc",80)
print("Count:", #Enemy._all)  -- 2
Enemy.destroyAll()

Lazy Initialization

Manche Felder sind aufwendig zu berechnen. Verwenden Sie __index mit einer Funktion, um sie beim ersten Zugriff zu berechnen und zwischenzuspeichern.

local BigData = {}
BigData.__index = function(t, k)
  if k == "processed" then
    print("Computing processed...")
    local result = {}
    for i,v in ipairs(rawget(t,"raw")) do result[i]=v*2 end
    rawset(t,"processed",result)
    return result
  end
end

function BigData.new(raw)
  return setmetatable({raw=raw}, BigData)
end

local d = BigData.new({1,2,3,4,5})
print(d.processed[3])  -- Computing...  6
print(d.processed[3])  -- 6 (cached, no recompute)

Prototyp aus einer Instanz

Klonen Sie eine Instanz, um eine weitere mit denselben Grundwerten zu erstellen. Der Klon erhält dieselbe Metatabelle (dieselbe Klasse) und eine Kopie der Instanzdaten. Das ist nützlich für „Vorlagen“-Objekte.

local Unit = {}
Unit.__index = Unit

function Unit.new(t)
  return setmetatable({name=t.name,hp=t.hp,atk=t.atk}, Unit)
end

function Unit:clone()
  return Unit.new({name=self.name,hp=self.hp,atk=self.atk})
end

function Unit:__tostring()
  return self.name.."(HP:"..self.hp..",ATK:"..self.atk..")"
end

local template = Unit.new({name="Soldier",hp=100,atk=10})
local u1 = template:clone(); u1.name="Alpha"
local u2 = template:clone(); u2.name="Beta"
print(tostring(u1),tostring(u2))

Fehlersicherheit des Konstruktors

Wenn die Konstruktion途中 fehlschlägt (z. B. bei der Ressourcenreservierung), müssen Sie sicherstellen, dass keine unvollständigen Objekte nach außen gelangen. Verwenden Sie pcall, um Konstruktionsfehler abzufangen und bei Bedarf Ressourcen freizugeben.

local FileHandle = {}
FileHandle.__index = FileHandle

function FileHandle.new(path, mode)
  local f, err = io.open(path, mode or "r")
  if not f then
    return nil, "cannot open " .. path .. ": " .. err
  end
  return setmetatable({_f=f, path=path}, FileHandle)
end

function FileHandle:read(fmt) return self._f:read(fmt) end
function FileHandle:close() self._f:close() end

local fh, err = FileHandle.new("data.txt")
if not fh then print("Error:", err)
else print(fh:read("l")); fh:close()
end

Kurztest

Welche Aufgabe hat ein Konstruktor (new()) in der objektorientierten Programmierung mit Lua?

Zusammenfassung: Konstruktoren

Zusammenfassung:

  • Konstruktor validiert und initialisiert und ruft setmetatable auf
  • Verwenden Sie eine Defaults-Tabelle für übersichtliche optionale Parameter
  • Mehrere Factory-Methoden für unterschiedliche Erzeugungsszenarien
  • Klonkonstruktor für Vorlagenobjekte
  • Lazy Initialization über __index für aufwendige Felder
  • Geben Sie bei einem Fehler im Konstruktor nil+err zurück (z. B. bei der Ressourcenreservierung)

Häufig gestellte Fragen

Ist die Lektion „Konstruktoren und new()“ kostenlos?

Ja — der vollständige Text von „Konstruktoren und new()“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Lua Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Lua Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Konstruktoren und new()“?

Schreiben Sie Konstruktorfunktionen, die Instanzen erstellen und initialisieren Du übst Lua Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Lua Academy zu starten?

Keine Vorkenntnisse erforderlich. Lua Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „Konstruktoren und new()“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Lua Academy-Lektion Code schreiben und ausführen?

Ja. Jede Lua Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Klassen über Metatabellen
  2. Konstruktoren und new()
  3. Instanzmethoden und self
  4. Kapselung mit Closures
← Zurück zu Lua Academy