Menu
Coddy logo textTech

Sobrescritura de métodos

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

Hasta ahora, las clases hijas han heredado los métodos de la clase padre y han añadido otros nuevos. ¿Pero qué pasa si una clase hija necesita el mismo nombre de método con un comportamiento diferente? Esto se conoce como sobrescritura de métodos (method overriding).

Cuando defines un método en una clase hija con el mismo nombre que uno en la clase padre, la versión de la hija tiene prioridad. La cadena de búsqueda de Lua comprueba primero la clase hija; si encuentra el método allí, deja de buscar.

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 sobrescribe speak()
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()
    print(self.name .. " barks: Woof!")
end

Ahora cada clase responde de manera diferente a la misma llamada de método:

local generic = Animal:new("Creature")
local buddy = Dog:new("Buddy")

generic:speak()  -- Salida: Creature hace un sonido
buddy:speak()    -- Salida: Buddy ladra: ¡Guau!

El :speak() de Dog reemplaza completamente la versión del padre para las instancias de Dog. Esto te permite crear un comportamiento especializado mientras mantienes una interfaz consistente: cada animal puede :speak(), pero cada especie lo hace de manera diferente.

challenge icon

Desafío

Fácil

¡Vamos a construir un pequeño reino animal donde diferentes criaturas hablan a su manera única! Crearás una clase base Animal y dos clases hijas—Cat y Cow—que sobrescribirán el método :speak() del padre con su propio comportamiento especializado.

Organizarás tu código en cuatro archivos:

  • Animal.lua: Tu clase base con un constructor :new(name) que almacena el nombre del animal. Incluye un método :speak() que imprima el nombre del animal seguido de makes a sound. Este es el comportamiento por defecto que las clases hijas sobrescribirán.
  • Cat.lua: Una clase hija que hereda de Animal. Su constructor :new(name) debe llamar al constructor del padre y luego volver a vincular la metatabla a Cat. Sobrescribe el método :speak() para que los gatos digan algo diferente—imprime el nombre del gato seguido de meows: Meow!
  • Cow.lua: Otra clase hija que hereda de Animal. Configura el constructor de la misma manera que Cat. Sobrescribe :speak() para que las vacas impriman su nombre seguido de moos: Moo!
  • main.lua: ¡Une todo! Lee dos nombres de la entrada, crea un Cat con el primer nombre y un Cow con el segundo nombre, luego llama a :speak() en cada uno para demostrar que el mismo nombre de método produce resultados diferentes según la clase.

Recibirás dos entradas:

  1. El nombre del gato
  2. El nombre de la vaca

En tu archivo principal, crea ambos animales y llama a :speak() primero en el gato y luego en la vaca.

Por ejemplo, si las entradas son Whiskers y Bessie, la salida debería ser:

Whiskers meows: Meow!
Bessie moos: Moo!

Observa cómo ambos animales responden a la misma llamada al método :speak(), pero cada uno produce una salida específica para su tipo. La versión de Cat reemplaza completamente el comportamiento genérico "makes a sound" del padre, al igual que la de Cow. ¡Esto es la sobrescritura de métodos en acción—misma interfaz, diferentes implementaciones!

Hoja de referencia

La anulación de métodos permite que una clase hija defina un método con el mismo nombre que un método del padre, reemplazando el comportamiento del padre con una funcionalidad especializada.

Cuando Lua busca un método, primero comprueba la clase hija. Si encuentra el método allí, utiliza esa versión y deja de buscar en la clase padre.

Ejemplo básico de anulació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

-- Dog overrides speak()
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()
    print(self.name .. " barks: Woof!")
end

Uso del método anulado:

local generic = Animal:new("Creature")
local buddy = Dog:new("Buddy")

generic:speak()  -- Output: Creature makes a sound
buddy:speak()    -- Output: Buddy barks: Woof!

El método de la clase hija reemplaza completamente la versión del padre para las instancias de esa clase hija, permitiendo un comportamiento especializado mientras se mantiene una interfaz consistente en todas las clases.

Pruébalo tú mismo

-- main.lua: Unir todo

local Cat = require('Cat')
local Cow = require('Cow')

-- Leer entrada
local catName = io.read()
local cowName = io.read()

-- TODO: Crear un Cat con el primer nombre

-- TODO: Crear un Cow con el segundo nombre

-- TODO: Llamar a :speak() en el gato primero, luego en la vaca
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