Añadir métodos hijos
Parte de la sección Object Oriented Programming del Journey de Lua de Coddy — lección 34 de 70.
La herencia permite que las clases hijas accedan a los métodos de los padres, pero el verdadero poder proviene de añadir nuevos métodos que solo tiene la hija. Un Dog puede hacer todo lo que un Animal puede, además de cosas únicas de los perros, como ladrar.
Agregar un método específico para la clase hija es sencillo: simplemente defínelo en la tabla de la clase hija. Dado que las instancias buscan los métodos primero en su propia clase, encontrarán el nuevo método sin afectar a la clase padre.
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print(self.name .. " is breathing")
end
-- Dog hereda de Animal
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
-- Nuevo método solo en Dog
function Dog:bark()
print(self.name .. " says: Woof!")
endAhora las instancias de Dog pueden usar tanto los métodos heredados como los únicos:
local buddy = Dog:new("Buddy")
buddy:breathe() -- Resultado: Buddy is breathing (heredado)
buddy:bark() -- Resultado: Buddy says: Woof! (solo del hijo)La clase padre permanece sin cambios; llamar a :bark() en un Animal simple fallaría, ya que ese método no existe allí. Así es como la herencia te permite especializar el comportamiento mientras mantienes la funcionalidad compartida en un solo lugar.
Desafío
Fácil¡Vamos a construir una jerarquía de mascotas donde los gatos tengan su propia habilidad especial! Crearás una clase padre Pet y una clase hija Cat, donde Cat hereda todo de Pet pero también tiene un método único que solo los gatos pueden hacer.
Organizarás tu código en tres archivos:
Pet.lua: Define tu clase padre con un constructor:new(name)que almacene el nombre de la mascota. Incluye un método:greet()que imprima el nombre de la mascota seguido desays hello. Configura el patrón de clase estándar y devuelve la clase.Cat.lua: Define tu clase hija que hereda de Pet. El constructor:new(name)de tu Cat debe llamar al constructor padre para inicializar el nombre, luego volver a vincular la metatabla a Cat. Agrega un método:purr()específico de la clase hija que imprima el nombre del gato seguido depurrs contentedly. ¡Este método solo existe en Cat—Pet no lo tiene!main.lua: Requiere tu módulo Cat, lee un nombre de la entrada, crea una instancia de Cat y demuestra que puede usar tanto el método heredado:greet()como su propio método único:purr().
Recibirás una entrada: el nombre del gato.
En tu archivo principal, crea un Cat con el nombre dado, luego llama a :greet() seguido de :purr() en líneas separadas.
Por ejemplo, si la entrada es Whiskers, la salida debería ser:
Whiskers says hello
Whiskers purrs contentedlyLa primera línea proviene del método heredado :greet() definido en Pet, mientras que la segunda línea proviene del método :purr() que solo existe en Cat. ¡Esto demuestra cómo las clases hijas pueden hacer todo lo que su padre puede, además de sus propios comportamientos especializados!
Hoja de referencia
Las clases hijas pueden añadir nuevos métodos que solo ellas poseen, mientras siguen heredando todos los métodos del padre. Las instancias buscan los métodos primero en su propia clase y luego recurren al padre.
Para añadir un método específico de la clase hija, defínelo en la tabla de la clase hija:
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print(self.name .. " is breathing")
end
-- Dog inherits from Animal
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
-- Child-specific method
function Dog:bark()
print(self.name .. " says: Woof!")
endLas instancias hijas pueden usar tanto los métodos heredados como los únicos:
local buddy = Dog:new("Buddy")
buddy:breathe() -- Inherited from Animal
buddy:bark() -- Child-only methodLa clase padre permanece inalterada; no tiene acceso a los métodos específicos de la clase hija.
Pruébalo tú mismo
-- main.lua: Crea un Cat y demuestra la herencia
local Cat = require('Cat')
-- Leer el nombre del gato desde la entrada
local name = io.read()
-- TODO: Crear una instancia de Cat con el nombre dado
-- TODO: Llamar al método heredado :greet() (de Pet)
-- TODO: Llamar al método :purr() específico de Cat
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