Lua Academy · leksjon

Kalle foreldremetoder med super

Kall basisklassemetoder eksplisitt for samarbeidsbasert initialisering.

Leksjon 2 av 412 trinn

Kalle foreldremetoder med super er en gratis leksjon i Lua Academy på CoddyKit. Dette er leksjon 2 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Lua Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Lua Academy inneholder totalt 4 leksjoner.

Hvorfor superkall

Når en underklasse overstyrer en metode fra forelderen, men fortsatt trenger logikken fra forelderen, kaller den foreldremetoden eksplisitt. Lua har ikke nøkkelordet super – De refererer direkte til foreldretabellen: Parent.method(self, args).

local Base={}
Base.__index=Base
function Base:describe()
  return "Base[name="..self.name.."]"
end

local Child={}
Child.__index=Child
setmetatable(Child,{__index=Base})

function Child:describe()
  local parentDesc = Base.describe(self)  -- super call
  return parentDesc .. " + Child[extra=true]"
end

local c=setmetatable({name="X"},Child)
print(c:describe())

Super i konstruktøren

Underklassens konstruktører kaller foreldrekonstruktører via Parent.new() eller Parent._init(self,...). Dette sørger for at initialiseringen fra forelderen kjøres for hver instans av underklassen.

local Animal={}
Animal.__index=Animal
function Animal._init(self,name,sound)
  self.name=name; self.sound=sound; self.alive=true
end

local Dog={}
Dog.__index=Dog; setmetatable(Dog,{__index=Animal})
function Dog.new(name,breed)
  local self=setmetatable({},Dog)
  Animal._init(self,name,"Woof")  -- super init
  self.breed=breed
  return self
end

local d=Dog.new("Rex","Lab")
print(d.name,d.sound,d.breed)

Kooperativ initialisering

I dype hierarkier initialiserer hvert nivå bare sine egne felt og kaller init-metoden til forelderen. Dette sørger for at hver klasse bare har ansvar for sine egne felt.

local A={}
function A._init(self,x) self.x=x end

local B={}
function B._init(self,x,y) A._init(self,x); self.y=y end

local C={}
C.__index=C
function C.new(x,y,z)
  local self=setmetatable({},C)
  B._init(self,x,y)
  self.z=z
  return self
end

local c=C.new(1,2,3)
print(c.x,c.y,c.z)  -- 1 2 3

super-wrapper

Opprett en hjelpefunksjon super(self) som returnerer et proxy-objekt som kaller foreldremetoder med self. Dette gir en ryddigere syntaks enn Parent.method(self, ...).

local function super(self)
  local mt = getmetatable(getmetatable(self).__index)
  if mt then
    return setmetatable({}, {__index=function(_,k)
      local parentCls = mt.__index or mt
      return function(...) return parentCls[k](self,...) end
    end})
  end
end
print("super() helper pattern shown")

Flere nivåer

Når det finnes flere arvenivåer, kaller hvert nivå den umiddelbare forelderen. Kjeden videreføres automatisk.

local L1={} L1.__index=L1
function L1:intro() return "L1" end

local L2={} L2.__index=L2
setmetatable(L2,{__index=L1})
function L2:intro() return L1.intro(self).."+L2" end

local L3={} L3.__index=L3
setmetatable(L3,{__index=L2})
function L3:intro() return L2.intro(self).."+L3" end

local obj=setmetatable({},L3)
print(obj:intro())  -- L1+L2+L3

Utvidelse av metoder

Utvid en foreldremetode: Kall foreldreversjonen, og legg deretter til ekstra oppførsel. Dette er «før»- eller «etter»-rådgivning uten et formelt AOP-rammeverk.

local Logger={} Logger.__index=Logger
function Logger:log(msg) print("[LOG] "..msg) end

local TimedLogger={} TimedLogger.__index=TimedLogger
setmetatable(TimedLogger,{__index=Logger})

function TimedLogger:log(msg)
  local ts=os.date("%H:%M:%S")
  Logger.log(self,"["..ts.."] "..msg)  -- augment
end

local tl=setmetatable({},TimedLogger)
tl:log("Server started")

Unngå fallgruver med super

Bruk alltid det nøyaktige navnet på foreldreklassen, ikke getmetatable(self).__index, for superkall – metatabelloppslaget kan returnere en mellomliggende klasse i stedet for den faktiske forelderen. Vær eksplisitt for å sikre tydelighet og korrekthet.

-- Correct: explicit parent reference
function Child:init(x)
  Base.init(self, x)  -- explicit, clear
end

-- Fragile: uses metatable lookup
function Child:initBad(x)
  local parent = getmetatable(getmetatable(self).__index)
  -- This may not be Base if hierarchy changes!
end
print("Be explicit with parent class references")

Super for __tostring

Overstyr __tostring i en underklasse, samtidig som De inkluderer representasjonen fra forelderen for å få en fullstendig beskrivelse.

local Base={}
Base.__index=Base
Base.__tostring=function(self) return "Base("..self.name..")" end

local Child={}
Child.__index=Child
setmetatable(Child,{__index=Base})
Child.__tostring=function(self)
  local baseStr = Base.__tostring(self)
  return baseStr.." + Child(level="..self.level..")"
end

local c=setmetatable({name="X",level=5},Child)
print(tostring(c))  -- Base(X) + Child(level=5)

Beskyttet template-metode

Template-metodemønsteret: Basisklassen definerer skjelettet for en algoritme med kall til abstrakte trinn, mens underklassene implementerer trinnene.

local Processor={} Processor.__index=Processor
function Processor:run(data)
  data = self:preProcess(data)
  data = self:process(data)
  return self:postProcess(data)
end
function Processor:preProcess(d) return d end
function Processor:postProcess(d) return d end
function Processor:process(d) error("implement process()") end

local Upper={} Upper.__index=Upper
setmetatable(Upper,{__index=Processor})
function Upper:process(d) return d:upper() end

local p=setmetatable({},Upper)
print(p:run("hello"))  -- HELLO

Konvensjon for superkall

Konvensjon: Sett _ først i interne init-funksjoner (for eksempel _init), og eksponer en offentlig new() bare i konstruktøren på øverste nivå. Dette holder arvekjeden ryddig.

-- Convention summary:
-- Animal._init(self, ...)  -- used for super calls
-- Dog.new(...)             -- only public constructor
-- Never call Dog._init from outside

local Foo={} Foo.__index=Foo
function Foo._init(self,x) self.x=x end
function Foo.new(x)
  return setmetatable({},Foo):_init(x) or
    (function() local s=setmetatable({},Foo); Foo._init(s,x); return s end)()
end
print("Convention: _init for super, new() for public")

Spørsmål om superkall

Hvordan kaller De en foreldremetode i Lua?

Oppsummering: Superkall

Kall alltid foreldremetoder med en eksplisitt klassereferanse: Parent.method(self, ...). Bruk konvensjonen med _init for kooperative konstruktører på tvers av arvenivåer.

Gratis å komme i gang

Lær deg Lua med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
40
Leksjoner
159

Ofte stilte spørsmål

Er leksjonen «Kalle foreldremetoder med super» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Lua Academy, inkludert «Kalle foreldremetoder med super», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Lua Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Kalle foreldremetoder med super»?

Kall basisklassemetoder eksplisitt for samarbeidsbasert initialisering. Du øver på Lua Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Lua Academy?

Ingen tidligere erfaring er nødvendig. Lua Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.

Hvor lang tid tar leksjonen «Kalle foreldremetoder med super»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Lua Academy-leksjonen?

Ja. Alle Lua Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Enkeltarv med __index-kjeding
  2. Kalle foreldremetoder med super
  3. Mixin-mønstre
  4. Overstyring og polymorfisme
← Tilbake til Lua Academy