Propiedades Calculadas
Parte de la sección Programación Orientada a Objetos 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. Deben ser calculados a partir de otros atributos. Estas se denominan propiedades calculadas.
Considera un rectángulo. Almacenas su ancho y su altura, pero el área no se almacena en ningún sitio: 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
endEl método :getArea() no devuelve un valor almacenado. Calcula el área desde cero cada vez que lo llamas. Este enfoque tiene una ventaja clave: si cambian el ancho o la altura, el área refleja automáticamente las nuevas dimensiones sin que tengas que actualizar nada.
local box = Rectangle:new(5, 3)
print(box:getArea()) -- Salida: 15
box.width = 10
print(box:getArea()) -- Salida: 30Las propiedades calculadas mantienen la coherencia de tus objetos. En lugar de almacenar valores que dependen de otros campos (y arriesgarte a que queden desactualizados), los calculas bajo demanda. Este patrón se aplica a cualquier dato derivado: perímetros, promedios, cadenas con formato o cualquier valor que pueda determinarse a partir de los atributos existentes.
Desafío
Fácil¡Construyamos una clase Box que calcule su volumen cuando se solicite! En lugar de almacenar el volumen como un campo, crearás una propiedad calculada que lo obtiene a partir de las dimensiones de la caja cada vez que se necesita.
Organizarás tu código en dos archivos:
Box.lua: Define tu claseBoxcon el patrón de prototipo estándar. Cada caja almacena tres dimensiones:width,heightydepth. Incluye:- Un constructor
:new(width, height, depth)que almacene las tres dimensiones - Un método
:getVolume()que calcule y devuelva el volumen (ancho × alto × profundidad) - Un método
:getSurfaceArea()que calcule y devuelva el área de superficie total
- Un constructor
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 así: 2 × (width×height + height×depth + width×depth)
Recibirás tres entradas que representan las dimensiones de la caja:
- Ancho
- Alto
- Profundidad
En tu archivo principal, crea una caja con las dimensiones proporcionadas y después imprime dos líneas:
- El volumen usando
:getVolume() - El área de superficie usando
:getSurfaceArea()
Por ejemplo, si las entradas son 3, 4 y 5, la salida debería ser:
60
94La ventaja de las propiedades calculadas es que siempre se mantienen precisas. Si más adelante cambiaras una de las dimensiones de la caja, llamar de nuevo a :getVolume() devolvería automáticamente el nuevo valor correcto: ¡no se necesitan actualizaciones manuales!
Pruébalo tú mismo
-- Requiere el módulo Box
local Box = require('Box')
-- Lee las dimensiones de entrada
local width = tonumber(io.read())
local height = tonumber(io.read())
local depth = tonumber(io.read())
-- TODO: Crea una instancia de box con las dimensiones dadas
-- TODO: Imprime el volumen usando :getVolume()
-- TODO: Imprime el área de superficie usando :getSurfaceArea()
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