Menu
Coddy logo textTech

Compartido vs. Único

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

Al trabajar con la herencia, es importante entender dónde reside cada fragmento de datos. Algunos atributos son compartidos: definidos en el padre y accesibles para todos los hijos. Otros son únicos: creados específicamente en la clase hija o 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
end
local 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 raza
    setmetatable(obj, Dog)
    return obj
end

Cuando 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 (lookup chain):

local rex = Dog:new("Rex", "German Shepherd")

-- Único para esta instancia (almacenado en rex)
print(rex.name)    -- "Rex"
print(rex.breed)   -- "German Shepherd"
-- Compartido (encontrado mediante búsqueda)
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 hijos.

challenge icon

Desafío

Fácil

Exploremos 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 padre con un atributo compartido a nivel de clase world = "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 hija que hereda de Creature. Añade un atributo compartido a nivel de clase element = "fire" que todos los dragones comparten. Tu constructor :new(name, color) debe llamar al constructor padre para el nombre, y luego añadir color como un atributo de instancia único para cada dragón.
  • main.lua: Crea dos dragones diferentes e inspecciona sus atributos para demostrar la diferencia entre datos compartidos y únicos.

Recibirás dos entradas:

  1. El nombre y color del primer dragón, separados por una coma (por ejemplo, Smaug,red)
  2. El nombre y 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. Luego imprime la siguiente información en este orden exacto:

  1. name del primer dragón
  2. color del primer dragón
  3. name del segundo dragón
  4. color del segundo dragón
  5. element del primer dragón (compartido de la clase Dragon)
  6. element del segundo dragón (compartido de la clase Dragon)
  7. world del primer dragón (compartido de 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 Realm

Observa 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 a través de la cadena de búsqueda).

Hoja de referencia

En las jerarquías de herencia, los atributos pueden ser **compartidos** (definidos en la tabla de la clase) o **únicos** (almacenados en instancias individuales).

Atributos compartidos se definen directamente en las tablas de clase y se accede a ellos a través de la cadena de búsqueda de metatablas:

local Animal = {}
Animal.__index = Animal
Animal.kingdom = "Animalia"  -- Compartido por todos los Animals

Atributos únicos se asignan al objeto de instancia (obj) en los constructores:

function Animal:new(name)
    local obj = {name = name}  -- Único para cada instancia
    setmetatable(obj, Animal)
    return obj
end

Las clases hijas pueden tener sus propios atributos compartidos mientras heredan los atributos del padre:

local 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)  -- Llamar al constructor padre
    obj.breed = breed  -- Añadir atributo único de la hija
    setmetatable(obj, Dog)
    return obj
end

Acceso a los atributos:

local rex = Dog:new("Rex", "German Shepherd")

-- Único (almacenado directamente en rex)
print(rex.name)    -- "Rex"
print(rex.breed)   -- "German Shepherd"

-- Compartido (encontrado mediante búsqueda en metatabla)
print(rex.sound)   -- "bark" (de la clase Dog)
print(rex.kingdom) -- "Animalia" (de la clase Animal)

Pruébalo tú mismo

-- main.lua: Crea dragones y demuestra atributos compartidos vs únicos

local Dragon = require('Dragon')

-- Leer entrada para el primer dragón (nombre,color)
local input1 = io.read()
-- Leer entrada para el segundo dragón (nombre,color)
local input2 = io.read()

-- TODO: Analizar la primera entrada para extraer el nombre y el color
-- Sugerencia: Usar string.match con el patrón "([^,]+),([^,]+)"

-- TODO: Analizar la segunda entrada para extraer el nombre y el color

-- TODO: Crear el primer dragón con su nombre y color

-- TODO: Crear el segundo dragón con su nombre y color

-- TODO: Imprimir 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)
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