Menu
Coddy logo textTech

Propiedades Calculadas

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

Los getters y setters proporcionan acceso a los valores almacenados, pero a veces necesitas datos que no existen como un campo almacenado; necesitan ser calculados a partir de otros atributos. Estas se denominan propiedades calculadas.

Considera un rectángulo. Almacenas su ancho y su alto, pero el área no se almacena en ningún lugar; se calcula multiplicando estos dos valores. En lugar de almacenar datos redundantes, creas un método que calcula y devuelve el resultado:

local Rectangle = {}
Rectangle.__index = Rectangle

function Rectangle:new(width, height)
    local instance = {}
    setmetatable(instance, self)
    instance.width = width
    instance.height = height
    return instance
end

function Rectangle:getArea()
    return self.width * self.height
end

El método :getArea() no devuelve un valor almacenado—calcula el área de nuevo cada vez que lo llamas. Este enfoque tiene una ventaja clave: si el ancho o el alto cambian, el área refleja automáticamente las nuevas dimensiones sin que necesites actualizar nada.

local box = Rectangle:new(5, 3)
print(box:getArea())  -- Salida: 15

box.width = 10
print(box:getArea())  -- Salida: 30

Las propiedades calculadas mantienen la consistencia de tus objetos. En lugar de almacenar valores que dependen de otros campos (y arriesgarse a que queden desactualizados), los calculas bajo demanda. Este patrón se aplica a cualquier dato derivado: perímetros, promedios, cadenas formateadas o cualquier valor que pueda determinarse a partir de atributos existentes.

challenge icon

Desafío

Fácil

¡Vamos a construir una clase Box que calcule su volumen bajo demanda! En lugar de almacenar el volumen como un campo, crearás una propiedad calculada que lo compute a partir de las dimensiones de la caja cada vez que sea necesario.

Organizarás tu código en dos archivos:

  • Box.lua: Define tu clase Box con el patrón de prototipo estándar. Cada caja almacena tres dimensiones: width, height y depth. Incluye:
    • Un constructor :new(width, height, depth) que almacene las tres dimensiones
    • Un método :getVolume() que calcule y devuelva el volumen (width × height × depth)
    • Un método :getSurfaceArea() que calcule y devuelva el área de superficie total
  • main.lua: Requiere tu módulo Box, crea una instancia de la caja y demuestra cómo las propiedades calculadas reflejan automáticamente las dimensiones actuales.

El área de superficie de una caja se calcula como: 2 × (width×height + height×depth + width×depth)

Recibirás tres entradas que representan las dimensiones de la caja:

  1. Ancho (Width)
  2. Alto (Height)
  3. Profundidad (Depth)

En tu archivo principal, crea una caja con las dimensiones dadas, luego imprime dos líneas:

  1. El volumen usando :getVolume()
  2. El área de superficie usando :getSurfaceArea()

Por ejemplo, si las entradas son 3, 4 y 5, la salida debería ser:

60
94

La belleza de las propiedades calculadas es que siempre se mantienen precisas. Si más tarde cambiaras una de las dimensiones de la caja, llamar a :getVolume() de nuevo devolvería automáticamente el nuevo valor correcto, ¡sin necesidad de actualizaciones manuales!

Hoja de referencia

Las propiedades calculadas son métodos que calculan y devuelven valores basados en otros atributos en lugar de almacenarlos directamente. Esto asegura la consistencia de los datos y elimina la redundancia.

Ejemplo de una propiedad calculada para el área:

local Rectangle = {}
Rectangle.__index = Rectangle

function Rectangle:new(width, height)
    local instance = {}
    setmetatable(instance, self)
    instance.width = width
    instance.height = height
    return instance
end

function Rectangle:getArea()
    return self.width * self.height
end

El método :getArea() calcula el área cada vez que se llama, reflejando automáticamente cualquier cambio en el ancho o el alto:

local box = Rectangle:new(5, 3)
print(box:getArea())  -- Resultado: 15

box.width = 10
print(box:getArea())  -- Resultado: 30

Las propiedades calculadas son útiles para cualquier dato derivado, como perímetros, volúmenes, promedios o cadenas formateadas que puedan determinarse a partir de los atributos existentes.

Pruébalo tú mismo

-- Requerir el módulo Box
local Box = require('Box')

-- Leer las dimensiones de entrada
local width = tonumber(io.read())
local height = tonumber(io.read())
local depth = tonumber(io.read())

-- TODO: Crear una instancia de box con las dimensiones dadas

-- TODO: Imprimir el volumen usando :getVolume()

-- TODO: Imprimir el área de superficie usando :getSurfaceArea()
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