0Pricing
Lua Academy · Lezione

Ereditarietà singola con concatenamento di __index

Imposti una classe padre come __index della metatabella per ereditare i metodi.

Ereditarietà singola con concatenamento di __index è una lezione Lua Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Lua Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Lua Academy include 4 lezioni in totale.

Catena di prototipi

L'ereditarietà singola funziona impostando __index della classe figlia sulla classe genitore. Quando un metodo non viene trovato nella figlia, Lua lo cerca nel genitore. In questo modo si crea una catena di prototipi.

local Base={}
Base.__index=Base
function Base.new() return setmetatable({},Base) end
function Base:greet() print("Hello from Base") end

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

function Child.new() return setmetatable({},Child) end

local c=Child.new()
c:greet()  -- Hello from Base (inherited)

Ordine di risoluzione dei metodi

Quando si chiama un metodo su un'istanza: (1) si cerca nella tabella dell'istanza, (2) si cerca in Child (tramite __index), (3) si cerca in Base (tramite __index della metatabella di Child). Vince la prima corrispondenza.

local Base={}
Base.__index=Base
function Base:who() print("I am Base") end

local Child={}
Child.__index=Child
setmetatable(Child,{__index=Base})
function Child:who() print("I am Child") end  -- override

local b=setmetatable({},Base)
local c=setmetatable({},Child)
b:who()  -- I am Base
c:who()  -- I am Child (overrides)

Ereditarietà dei costruttori

Le classi figlie possono riutilizzare i costruttori dei genitori chiamandoli oppure definirne di propri che estendono l'inizializzazione del genitore.

local Animal={}
Animal.__index=Animal
function Animal.new(name,sound)
  return setmetatable({name=name,sound=sound},Animal)
end
function Animal:speak() print(self.name..": "..self.sound) end

local Dog={}
Dog.__index=Dog
setmetatable(Dog,{__index=Animal})

function Dog.new(name)
  local self = Animal.new(name,"Woof")
  return setmetatable(self,Dog)
end
function Dog:fetch(item) print(self.name.." fetches "..item) end

local d=Dog.new("Rex")
d:speak(); d:fetch("ball")

Verificare la gerarchia

Risalga lungo la catena delle metatabelle per verificare se la classe di un oggetto eredita da una determinata base. È così che funziona instanceof in Lua.

local function instanceof(obj, cls)
  local mt = getmetatable(obj)
  while mt do
    if mt == cls then return true end
    mt = getmetatable(mt)
  end
  return false
end

Chiamata al super

Chiami la versione del genitore di un metodo sovrascritto accedendovi direttamente tramite la tabella della classe genitore.

local Base={}
Base.__index=Base
function Base:init(x) self.x=x end
function Base:value() return self.x end

local Child={}
Child.__index=Child
setmetatable(Child,{__index=Base})
function Child:init(x,y)
  Base.init(self,x)  -- call parent
  self.y=y
end
function Child:value() return Base.value(self)+self.y end

local c=setmetatable({},Child)
c:init(3,4)
print(c:value())  -- 7

Catena profonda

Costruisca una gerarchia a tre livelli: A → B → C. La ricerca dei metodi attraversa l'intera catena finché non trova il metodo.

local A={}
A.__index=A
function A:aMethod() print("A method") end

local B={}
B.__index=B
setmetatable(B,{__index=A})
function B:bMethod() print("B method") end

local C={}
C.__index=C
setmetatable(C,{__index=B})

local c=setmetatable({},C)
c:bMethod()  -- from B
c:aMethod()  -- from A

Sovrascrivere i campi

Un'istanza può sovrascrivere i campi a livello di classe impostandoli direttamente. Il campo della classe non cambia: viene semplicemente nascosto per quell'istanza.

local Creature={}
Creature.__index=Creature
Creature.hp=100
Creature.speed=10

function Creature.new()
  return setmetatable({},Creature)
end

local fast=Creature.new()
fast.speed=20  -- override for this instance

local normal=Creature.new()

print(fast.speed,normal.speed,Creature.speed)  -- 20  10  10

Ereditarietà a livello di classe

Impostare setmetatable(Child, {__index=Parent}) fa sì che le ricerche a livello di classe proseguano nella classe genitore. Ciò significa che Child.classMethod() trova i metodi della classe genitore se non sono stati sovrascritti.

local Vehicle={}
Vehicle.__index=Vehicle
Vehicle.maxSpeed=120
function Vehicle.describe() print("Vehicle") end

local Car={}
Car.__index=Car
setmetatable(Car,{__index=Vehicle})

Car.describe()  -- Vehicle (inherited class method)
print(Car.maxSpeed)  -- 120 (inherited class field)

Catena di inizializzazione

Per un'inizializzazione corretta, i costruttori delle classi figlie chiamano quelli dei genitori per assicurarsi che lo stato del genitore venga configurato. Propaghi l'inizializzazione lungo la gerarchia.

local Base={}
Base.__index=Base
function Base:_init(name) self.name=name end

local Mid={}
Mid.__index=Mid
setmetatable(Mid,{__index=Base})
function Mid:_init(name,level)
  Base._init(self,name)
  self.level=level
end

local Top={}
Top.__index=Top
setmetatable(Top,{__index=Mid})
function Top.new(name,level,role)
  local self=setmetatable({},Top)
  Mid._init(self,name,level)
  self.role=role
  return self
end

local t=Top.new("Alice",5,"admin")
print(t.name,t.level,t.role)

Classi base astratte

Crei una classe base con metodi non implementati che generano errori. Le sottoclassi devono sovrascrivere questi metodi. Questo impone i contratti delle interfacce nel sistema a tipizzazione dinamica di Lua.

local Serializer={}
Serializer.__index=Serializer
function Serializer:encode(data)
  error(self._type.." must implement encode()",2)
end
function Serializer:decode(str)
  error(self._type.." must implement decode()",2)
end

local JSONSerializer={_type="JSON"}
setmetatable(JSONSerializer,{__index=Serializer})
function JSONSerializer:encode(data)
  return "{"..tostring(data.key).."}"
end

local j=setmetatable({_type="JSON"},JSONSerializer)
print(j:encode({key="val"}))

Domanda sull'ereditarietà

Che cosa abilita l'ereditarietà singola in Lua?

Riepilogo: ereditarietà singola

Imposti setmetatable(Child, {__index = Parent}) per ereditare i metodi. La catena di __index fornisce la delegazione automatica. Sovrascriva un metodo definendolo in Child; chiami esplicitamente il genitore con Parent.method(self).

Domande Frequenti

La lezione «Ereditarietà singola con concatenamento di __index» è gratuita?

Sì — il testo completo di «Ereditarietà singola con concatenamento di __index» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Lua Academy, passa a CoddyKit PRO. Il corso Lua Academy include 4 lezioni in totale.

Cosa imparerò in «Ereditarietà singola con concatenamento di __index»?

Imposti una classe padre come __index della metatabella per ereditare i metodi. Eserciti Lua Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Lua Academy?

Non è richiesta alcuna esperienza precedente. Lua Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Ereditarietà singola con concatenamento di __index»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Lua Academy?

Sì. Ogni lezione Lua Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Ereditarietà singola con concatenamento di __index
  2. Chiamata dei metodi del padre con super
  3. Pattern mixin
  4. Override e polimorfismo
← Torna a Lua Academy