Konstruktører og new()
Skriv konstruktørfunktioner, der opretter og initialiserer instanser.
Konstruktører og new() er en gratis Lua Academy-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Lua Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Lua Academy-kurset indeholder 4 lektioner i alt.
Konstruktørens ansvar
En konstruktør opretter og initialiserer en instans. Den modtager startværdier, validerer dem, angiver standardværdier for manglende felter og returnerer den nye instans. En veldesignet konstruktør sikrer, at alle instanser starter i en gyldig tilstand.
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 50Flydende konstruktør
En flydende konstruktør returnerer self fra setter-metoder, så du kan kæde metoder under oprettelsen. Dette er et builder-mønster i 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)Kopikonstruktør
En kopikonstruktør opretter en ny instans med de samme værdier som en eksisterende instans. Vigtigt: Brug en overfladisk eller dyb kopi afhængigt af, om indlejrede tabeller skal deles eller være uafhængige.
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)Konstruktør med validering
Validér altid konstruktørens input. Kast beskrivende fejl ved ugyldigt input på niveau 2 (den kaldende kode har ansvaret). Det opdager fejl tidligt og giver nyttige fejlmeddelelser.
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 16Mønsteret med standardværdier
Brug en tabel med standardværdier til at håndtere valgfrie konstruktørparametre på en enkel måde. Det undgår lange kæder af x = x or default og gør standardværdierne tydelige og nemme at ændre.
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 1Statiske fabriksmetoder
En klasse kan have flere fabriksmetoder til forskellige oprettelsesscenarier. Det er mere overskueligt end at overbelaste en enkelt konstruktør med mange valgfrie parametre.
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()) -- #FF0000Konstruktørregister
Brug et register til at holde styr på alle instanser. Det gør globale handlinger som "ødelæg alle" eller gennemløb af alle objekter af en bestemt type mulige.
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()Doven initialisering
Nogle felter er dyre at beregne. Brug __index sammen med en funktion til at beregne og cache dem ved første adgang.
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)Prototype fra instans
Klon en instans for at oprette en anden med de samme grundværdier. Klonen får den samme metatabel (den samme klasse) og en kopi af instansens data. Det er nyttigt til "skabelonobjekter".
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))Fejlsikkerhed i konstruktøren
Hvis oprettelsen mislykkes undervejs (f.eks. ved allokering af en ressource), skal du sikre, at ingen delvist oprettede objekter slipper ud. Brug pcall til at fange fejl under oprettelsen, og ryd om nødvendigt ressourcer op.
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()
endHurtigt tjek
Hvilken rolle har en konstruktør (new()) i Luas OOP?
Opsummering: Konstruktører
Opsummering:
- Konstruktøren validerer, initialiserer og kalder setmetatable
- Brug en tabel med standardværdier til rene valgfrie parametre
- Flere fabriksmetoder til forskellige oprettelsesscenarier
- Kloningskonstruktør til skabelonobjekter
- Doven initialisering via __index til dyre felter
- Returnér nil+err fra konstruktøren ved fejl (allokering af en ressource)
Lær Lua med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 40
- Lektioner
- 159
Ofte stillede spørgsmål
Er lektionen “Konstruktører og new()” gratis?
Ja — alle 3 lektioner i læringssporet Lua Academy, inklusive “Konstruktører og new()”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Lua Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Konstruktører og new()”?
Skriv konstruktørfunktioner, der opretter og initialiserer instanser. Du øver dig i Lua Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Lua Academy?
Der kræves ingen tidligere erfaring. Lua Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.
Hvor lang tid tager lektionen “Konstruktører og new()”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Lua Academy-lektion?
Ja. Alle Lua Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Klasser via metatabeller
- Konstruktører og new()
- Instansmetoder og self
- Indkapsling med closures