Menu
Coddy logo textTech

Herencia de métodos

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

Con el vínculo de herencia establecido, las instancias de la clase hija obtienen automáticamente acceso a todos los métodos del padre. Esto sucede a través de la cadena de búsqueda de Lua: cuando llamas a un método en una instancia, Lua busca a través de cada tabla conectada hasta que encuentra lo que estás buscando.

Considera esta configuración donde Animal define un método :breathe():

local Animal = {}
Animal.__index = Animal

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

function Animal:breathe()
    print("Breathing...")
end

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

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

Ahora observa lo que sucede cuando creamos un Dog y llamamos al método del padre:

local buddy = Dog:new()
buddy:breathe()  -- Salida: Respirando...

La clase Dog nunca definió :breathe(), pero aun así funciona. Lua primero busca en buddy, no encuentra nada, luego busca en Dog, sigue sin haber nada, y finalmente lo encuentra en Animal. Esta herencia automática de métodos significa que escribes el comportamiento compartido una vez en el padre y cada clase hija se beneficia de inmediato.

challenge icon

Desafío

Fácil

¡Vamos a construir una jerarquía simple de criaturas para ver la herencia de métodos en acción! Crearás una clase padre Animal y una clase hija Dog, luego demostrarás que las instancias de Dog pueden usar métodos definidos solo en Animal.

Organizarás tu código en tres archivos:

  • Animal.lua: Define tu clase padre con el patrón de clase estándar. Incluye un constructor :new(name) que almacene el nombre del animal, y un método :speak() que imprima el nombre del animal seguido de makes a sound. Devuelve la clase al final del archivo.
  • Dog.lua: Define tu clase hija que hereda de Animal. Requiere el módulo Animal y establece el enlace de herencia para que Dog pueda acceder a los métodos de Animal. Incluye un constructor :new(name) que almacene el nombre y establezca Dog como la metatabla. La clase Dog NO debe definir su propio método :speak(); lo heredará de Animal.
  • main.lua: Requiere tu módulo Dog, lee un nombre de la entrada, crea una instancia de Dog con ese nombre y llama al método :speak() en ella.

Recibirás una entrada: el nombre del perro.

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

Buddy makes a sound

La magia aquí es que tu clase Dog nunca define :speak(), pero llamarlo en una instancia de Dog funciona perfectamente. Lua sigue la cadena de búsqueda desde la instancia de Dog hacia la clase Dog, y luego hacia la clase Animal donde encuentra el método. ¡Esto es la herencia en funcionamiento!

Hoja de referencia

Las instancias de las clases hijas obtienen automáticamente acceso a todos los métodos de la clase padre a través de la cadena de búsqueda de Lua. Cuando se llama a un método en una instancia, Lua busca a través de cada tabla conectada hasta que encuentra el método.

Configuración de la Herencia

Definición de la clase padre:

local Animal = {}
Animal.__index = Animal

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

function Animal:breathe()
    print("Breathing...")
end

Clase hija con enlace de herencia:

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

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

Uso de Métodos Heredados

Las instancias hijas pueden llamar a métodos del padre incluso si no están definidos en la clase hija:

local buddy = Dog:new()
buddy:breathe()  -- Output: Breathing...

La cadena de búsqueda: Lua comprueba buddyDogAnimal hasta que encuentra el método.

Organización de Clases en Múltiples Archivos

Archivo de la clase padre (Animal.lua):

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

return Animal

Archivo de la clase hija (Dog.lua):

local Animal = require("Animal")

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

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

return Dog

Uso en el archivo principal:

local Dog = require("Dog")
local buddy = Dog:new("Buddy")
buddy:speak()  -- Output: Buddy makes a sound

Pruébalo tú mismo

-- main.lua: Punto de entrada

local Dog = require('Dog')

-- Leer el nombre del perro desde la entrada
local name = io.read()

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

-- TODO: Llamar al método :speak() en la instancia del perro
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