0Pricing
Lua Academy · Lección

Llamada a métodos de la clase principal con super

Llame explícitamente a los métodos de la clase base para realizar una inicialización cooperativa.

Llamada a métodos de la clase principal con super es una lección gratuita de Lua Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Lua Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Lua Academy incluye 4 lecciones en total.

¿Por qué hacer llamadas al padre?

Cuando una hija sobrescribe un método del padre, pero aún necesita su lógica, llama explícitamente al método del padre. Lua no tiene la palabra clave super; se hace referencia directamente a la tabla del padre: 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())

Llamada al padre en el constructor

Los constructores hijos llaman a los constructores padres mediante Parent.new() o Parent._init(self,...). Esto garantiza que la inicialización del padre se ejecute para cada instancia hija.

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)

Inicialización cooperativa

En las jerarquías profundas, cada nivel inicializa únicamente sus propios campos y llama a la inicialización del padre. Así, cada clase se responsabiliza solo de sus propios campos.

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

Envoltorio super

Cree un auxiliar super(self) que devuelva un objeto proxy que llame a los métodos del padre con self. Esto ofrece una sintaxis más limpia que 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")

Varios niveles

Cuando hay varios niveles de herencia, cada nivel llama a su padre inmediato. La cadena se propaga automáticamente.

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

Ampliación de métodos

Amplíe un método del padre: llame a la versión del padre y después añada comportamiento adicional. Esto equivale a un advice «antes» o «después» sin un framework AOP formal.

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")

Evitar problemas con las llamadas al padre

Use siempre el nombre exacto de la clase padre, no getmetatable(self).__index, para hacer llamadas al padre: la búsqueda mediante metatablas puede devolver una clase intermedia, no el padre verdadero. Sea explícito para mantener la claridad y la corrección.

-- 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 para __tostring

Sobrescriba __tostring en una hija e incluya la representación del padre para obtener una descripción completa.

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)

Método plantilla protegido

El patrón de método plantilla: la clase base define el esqueleto de un algoritmo con llamadas a pasos abstractos; las subclases implementan esos pasos.

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

Convención para las llamadas al padre

Convención: anteponga _ a las funciones de inicialización de uso interno (por ejemplo, _init) y exponga un new() público únicamente en el constructor del nivel superior. Así se mantiene limpia la cadena de herencia.

-- 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")

Pregunta sobre llamadas al padre

¿Cómo se llama a un método del padre en Lua?

Repaso: llamadas al padre

Llame siempre a los métodos del padre mediante una referencia explícita a la clase: Parent.method(self, ...). Use la convención _init para los constructores cooperativos a través de los distintos niveles de herencia.

Preguntas frecuentes

¿La lección «Llamada a métodos de la clase principal con super» es gratis?

Sí — el texto completo de «Llamada a métodos de la clase principal con super» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Lua Academy, actualiza a CoddyKit PRO. El curso de Lua Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Llamada a métodos de la clase principal con super»?

Llame explícitamente a los métodos de la clase base para realizar una inicialización cooperativa. Practicas Lua Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Lua Academy?

No se requiere experiencia previa. Lua Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.

¿Cuánto tiempo toma la lección «Llamada a métodos de la clase principal con super»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Lua Academy?

Sí. Cada lección de Lua Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Herencia simple con encadenamiento de __index
  2. Llamada a métodos de la clase principal con super
  3. Patrones mixin
  4. Sobrescritura y polimorfismo
← Volver a Lua Academy