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
endAhora 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.
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 demakes 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 soundLa 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...")
endClase hija con enlace de herencia:
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new()
local obj = {}
setmetatable(obj, Dog)
return obj
endUso 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 buddy → Dog → Animal 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 AnimalArchivo 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 DogUso en el archivo principal:
local Dog = require("Dog")
local buddy = Dog:new("Buddy")
buddy:speak() -- Output: Buddy makes a soundPrué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
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Object Oriented Programming
1El concepto de 'self'
Tablas con funciones'self' explícitoLa sintaxis de dos puntosPunto vs. dos puntosResumen - Punto en movimiento4Proyecto: Banco Digital
Configuración del proyectoMétodo de depósito2Patrón de prototipo de clase
El concepto de prototipoVinculación con __indexEl constructor :new()Inicialización de atributosInstancias independientesResumen - Fábrica de coches5Sobrecarga de operadores en POO
Sumar objetosRestar objetosConcatenar objetosComparar objetos (<, >)Resumen - Matemáticas de la billetera8Encapsulamiento
Convenciones de nomenclaturaClosures para privacidadAcceso mediante ClosuresTablas de solo lecturaLógica de validaciónResumen - Bóveda segura11Patrones de diseño (Lite)
Funciones FactoryTabla SingletonPatrón IteradorObserver (Listener)Resumen - Logger Factory3Estado y Comportamiento de los Objetos
Variables de InstanciaMétodos GetterMétodos SetterPropiedades CalculadasFormateo de StringsComprobaciones de IgualdadResumen - Calificación del Estudiante6Fundamentos de la herencia
Configuración de la herenciaHerencia de métodosExtender el constructorAñadir métodos hijosCompartido vs. ÚnicoResumen: Jerarquía de formas