Compartido vs. Único
Parte de la sección Programación Orientada a Objetos del Journey de Lua de Coddy. Lección 35 de 70.
Al trabajar con la herencia, es importante comprender dónde se encuentra cada elemento de datos. Algunos atributos son compartidos: se definen en la clase principal y son accesibles para todos los elementos secundarios. Otros son únicos: se crean específicamente en la clase secundaria o en la instancia.
Considera esta jerarquía:
local Animal = {}
Animal.__index = Animal
Animal.kingdom = "Animalia" -- Compartido: definido en la clase
function Animal:new(name)
local obj = {name = name} -- Único: almacenado en cada instancia
setmetatable(obj, Animal)
return obj
endlocal Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
Dog.sound = "bark" -- Compartido entre todos los Dogs
function Dog:new(name, breed)
local obj = Animal.new(Animal, name)
obj.breed = breed -- Único: cada Dog tiene su propia breed
setmetatable(obj, Dog)
return obj
endCuando creas una instancia de Dog, algunos valores existen directamente en el objeto, mientras que otros se encuentran a través de la cadena de búsqueda:
local rex = Dog:new("Rex", "German Shepherd")
-- Único de esta instancia (almacenado en rex)
print(rex.name) -- "Rex"
print(rex.breed) -- "German Shepherd"-- Compartido (encontrado mediante lookup)
print(rex.sound) -- "bark" (de Dog)
print(rex.kingdom) -- "Animalia" (de Animal)La distinción clave: los campos asignados a obj en los constructores son únicos para cada instancia, mientras que los campos definidos directamente en las tablas de clase se comparten entre todas las instancias de esa clase y sus clases derivadas.
Desafío
FácilExploremos cómo fluyen los datos a través de una jerarquía de herencia construyendo un sistema de clases Creature y Dragon. Verás de primera mano qué atributos se comparten entre todas las instancias y cuáles son únicos para cada objeto individual.
Organizarás tu código en tres archivos:
Creature.lua: Define tu clase principal con un atributo compartido de nivel de claseworld = "Fantasy Realm"que todas las criaturas comparten. Incluye un constructor:new(name)que almacene el nombre de la criatura como un atributo de instancia.Dragon.lua: Define tu clase secundaria, que hereda de Creature. Añade un atributo compartido de nivel de claseelement = "fire"que todos los dragones compartan. Tu constructor:new(name, color)debe llamar al constructor de la clase principal para el nombre y, después, añadircolorcomo un atributo de instancia único para cada dragón.main.lua: Crea dos dragones diferentes e inspecciona sus atributos para demostrar la diferencia entre los datos compartidos y los únicos.
Recibirás dos entradas:
- El nombre y el color del primer dragón, separados por una coma (por ejemplo,
Smaug,red) - El nombre y el color del segundo dragón, separados por una coma (por ejemplo,
Draco,gold)
En tu archivo principal, crea ambos dragones con sus respectivos nombres y colores. Después, imprime la siguiente información en este orden exacto:
- El
namedel primer dragón - El
colordel primer dragón - El
namedel segundo dragón - El
colordel segundo dragón - El
elementdel primer dragón (compartido desde la clase Dragon) - El
elementdel segundo dragón (compartido desde la clase Dragon) - El
worlddel primer dragón (compartido desde la clase Creature)
Por ejemplo, si las entradas son Smaug,red y Draco,gold, la salida debería ser:
Smaug
red
Draco
gold
fire
fire
Fantasy RealmObserva cómo name y color son diferentes para cada dragón (atributos de instancia únicos), mientras que element y world son iguales para ambos (atributos de clase compartidos encontrados mediante la cadena de búsqueda).
Pruébalo tú mismo
-- main.lua: Crea dragones y demuestra atributos compartidos vs únicos
local Dragon = require('Dragon')
-- Lee la entrada del primer dragón (name,color)
local input1 = io.read()
-- Lee la entrada del segundo dragón (name,color)
local input2 = io.read()
-- TODO: Parsea la primera entrada para extraer name y color
-- Hint: Usa string.match con el patrón "([^,]+),([^,]+)"
-- TODO: Parsea la segunda entrada para extraer name y color
-- TODO: Crea el primer dragón con su name y color
-- TODO: Crea el segundo dragón con su name y color
-- TODO: Imprime lo siguiente en orden:
-- 1. Nombre del primer dragón
-- 2. Color del primer dragón
-- 3. Nombre del segundo dragón
-- 4. Color del segundo dragón
-- 5. Elemento del primer dragón (compartido de la clase Dragon)
-- 6. Elemento del segundo dragón (compartido de la clase Dragon)
-- 7. Mundo del primer dragón (compartido de la clase Creature)
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
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 formasPractica por tu cuenta: Compilador de Lua online