Menu
Coddy logo textTech

Llamar a métodos del padre

Parte de la sección Object Oriented Programming del Journey de Lua de Coddy — lección 38 de 70.

A veces, sobrescribir un método por completo no es lo que deseas. En su lugar, es posible que desees extender el comportamiento del padre: hacer lo que hace el padre y luego añadir algo extra. Para lograr esto, puedes llamar al método del padre directamente desde la sobrescritura del hijo.

La técnica utiliza la sintaxis de punto con el nombre de la clase padre, pasando explícitamente self como el primer argumento:

local Animal = {}
Animal.__index = Animal

function Animal:new(name)
    local obj = {name = name}
    setmetatable(obj, Animal)
    return obj
end

function Animal:speak()
    print(self.name .. " makes a sound")
end

-- Dog extiende el comportamiento del padre
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})

function Dog:new(name)
    local obj = Animal.new(Animal, name)
    setmetatable(obj, Dog)
    return obj
end

function Dog:speak()
    Animal.speak(self)  -- Llama primero al método del padre
    print(self.name .. " wags tail happily")
end

La línea clave es Animal.speak(self). Al usar la sintaxis de punto en la clase padre y pasar self manualmente, invocamos el método original antes de añadir nuestro propio comportamiento:

local buddy = Dog:new("Buddy")
buddy:speak()
-- Salida:
-- Buddy hace un sonido
-- Buddy menea la cola alegremente

Este patrón es útil cuando el método padre realiza un trabajo importante que no quieres duplicar. El hijo puede ejecutar la lógica del padre primero, al final o incluso en medio de su propio código, lo que te da un control total sobre cómo se combinan los comportamientos.

challenge icon

Desafío

Fácil

¡Vamos a construir un sistema de saludo donde un FormalPerson extiende el comportamiento de una Person regular! En lugar de reemplazar completamente cómo se presenta una persona, la versión formal primero hará la presentación estándar y luego añadirá un toque extra de cortesía.

Organizarás tu código en tres archivos:

  • Person.lua: Tu clase base con un constructor :new(name) que almacena el nombre de la persona. Incluye un método :introduce() que imprime el nombre de la persona seguido de says hi. Este es el comportamiento base que será extendido.
  • FormalPerson.lua: Una clase hija que hereda de Person. Su constructor debe llamar al constructor del padre para manejar el nombre. Sobrescribe el método :introduce(), pero en lugar de reemplazar el comportamiento del padre por completo, llama primero al método del padre usando Person.introduce(self), luego imprime una línea adicional con el nombre de la persona seguido de bows politely.
  • main.lua: Requiere tu módulo FormalPerson, lee un nombre de la entrada, crea una instancia de FormalPerson y llama a :introduce() para ver ambos comportamientos combinados.

Recibirás una entrada: el nombre de la persona.

Cuando llames a :introduce() en un FormalPerson, debería producir dos líneas de salida: la primera del método del padre y la segunda de la adición del hijo:

{name} says hi
{name} bows politely

Por ejemplo, si la entrada es Eleanor, la salida debería ser:

Eleanor says hi
Eleanor bows politely

La clave aquí es que FormalPerson no duplica la lógica de "says hi"; delega ese trabajo al método del padre y luego añade su propio comportamiento único encima. ¡Esto mantiene tu código limpio y demuestra cómo las clases hijas pueden extender en lugar de reemplazar la funcionalidad del padre!

Hoja de referencia

Para extender el comportamiento de un método padre en lugar de sobrescribirlo por completo, llama al método padre desde la sobrescritura del hijo usando la sintaxis de punto y pasando explícitamente self:

function ChildClass:method()
    ParentClass.method(self)  -- Llamar al método padre
    -- Añadir comportamiento adicional
end

Ejemplo completo que muestra la extensión de métodos:

local Animal = {}
Animal.__index = Animal

function Animal:new(name)
    local obj = {name = name}
    setmetatable(obj, Animal)
    return obj
end

function Animal:speak()
    print(self.name .. " makes a sound")
end

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

function Dog:new(name)
    local obj = Animal.new(Animal, name)
    setmetatable(obj, Dog)
    return obj
end

function Dog:speak()
    Animal.speak(self)  -- Ejecutar primero el comportamiento del padre
    print(self.name .. " wags tail happily")  -- Añadir comportamiento del hijo
end

local buddy = Dog:new("Buddy")
buddy:speak()
-- Salida:
-- Buddy makes a sound
-- Buddy wags tail happily

El método padre se puede llamar en cualquier punto: antes, después o en medio de la propia lógica del hijo, lo que otorga un control total sobre cómo se combinan los comportamientos.

Pruébalo tú mismo

-- main.lua: Punto de entrada para el sistema de saludos

local FormalPerson = require('FormalPerson')

-- Leer el nombre de la persona desde la entrada
local name = io.read()

-- TODO: Crear una instancia de FormalPerson con el nombre dado

-- TODO: Llamar al método introduce en la instancia de FormalPerson
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Object Oriented Programming