👽
3ntr0 Apuntes
  • 📚Principios SOLID y Clean Code
    • 💲Deuda Técnica
    • 📌Mejorar Nombres
      • 📄Nombre según Tipo
      • 🚗Nombre Clases
      • ⚙️Nombres Funciones
    • ☑️Mejorar Funciones
    • ➿Principio DRY
    • 🧼Clean Code en Clases (POO)
      • 📘 Principio de Responsabilidad Única (SRP)
    • 🤮🇸 🇹 🇺 🇵 🇮 🇩 - Code Smells
      • 🚫Singleton
      • 🙏Tight Coupling
      • 🥸U P I D
      • 🚩Más Code Smells
  • 💕Angular
    • 🏍️Standalone
    • 🆚ngClass vs [class.clase]
    • 🩻Directivas
    • 🚩ElementRef
    • 🎀Decoradores
      • @HostListener
    • 🔄OnChanges
    • 🧪Testing - Jasmine y Karma
      • 🚀Módulo 1: Introducción a las pruebas unitarias
      • 🧫Módulo 2: Introducción a Jasmine
      • ⚒️Módulo 3: Introducción a Karma
      • 🔬Módulo 4: Pruebas unitarias en Angular
        • Código comentado Paso a Paso
      • 🕵️‍♂️Módulo 5: Técnicas avanzadas en Jasmine
      • 📚Módulo 6: Técnicas avanzadas en Karma
  • 🖼️HTML y CSS
    • 🖌️Custom Properties
    • Trucos
    • Brakepoints
  • 🧋Javascript
    • 🛠️Funciones
    • 📦Arrays
      • Every y Some
      • Map
      • Reduce
    • 😎Hoisting
    • 🪚Desestructuración
    • 🛻Programación Asincrona
      • 📞Callbacks
      • 🌟Promises
      • 🆚Promise.all Y Promise.any
      • 🚀Async/Await
    • Respuestas HTTP
    • 🧐Dudas Básicas
      • NodeList
      • 🧐Contextos de .this
      • 💭Parametro Rest
      • 🗨️arguments
      • 🙀JavaScript no tiene clases
      • 🆚Null vs Undefined
      • 🔎Operador in
      • 🟨Operador Spread
      • ❓Encadenamiento Opcional
      • 🔲Notación de Corchetes
      • ⛓️Coalescencia Nula (??)
      • 🆚Shallow Copy vs Deep Copy
      • 🆚.json VS JSON.parse
      • ⚙️Fetch wrapper
      • Sets
      • Maps
  • 📒Terminología
    • 💎Esenciales
    • Web
    • Javascript
  • 🌐GIT
    • Source Tree
  • 🧬React
    • 🫂Babel
  • 🔧 Fundamentos de C#
    • 🎛️General
      • 🧐Diferencia Equals y ==
      • 🧐Diferencia entre typeof y .GetType()
      • 📐Convenciones de Nomenclatura
    • 💠Summary
    • 📇.resx
    • 📄Strings
      • ⛓️Comparación de cadenas
    • 🧲Regex
    • 📦POO
      • 🚙Clases
        • ✏️Clase String
        • 📥Métodos de Acceso
        • ⚗️Métodos de Extensión
    • 🖇️Pattern Matching
    • 🚩Excepciones
    • Programación Asíncrona
    • 🔎LINQ
      • 🅿️PLINQ
  • 🌐 Desarrollo Web con ASP.NET
    • 🧬Modelos
      • 🗒️Data Annotations
        • 📑Lista
        • 🧪Atributos
          • 🛠️Atributos Personalizados
          • 🧰AttributeUsage
          • 📥Acceso a los atributos
        • 📚Documentación
    • 👷Servicios
      • ⭐Servicios Singleton
    • ⏳Sesiones
      • 🧭Temp Data
    • DbContext
      • 🔄Eager Loading
    • 🥽Manejo de Datos
      • 🗃️Archivos
        • 📤Subida de Archivos
        • ✏️Leer y Escribir
        • 🕓Manejo de Archivos Temporales
        • 🛡️Validación de Archivos en ASP.NET Core
      • Colecciones
        • 🪜Pila (Stack)
        • 🏇Cola (Queue)
      • 🩻Manejo de XMLs
        • 📂XmlDocument
          • 🎯XPath
        • 🧿XmlReader
    • ❤️Tips y Utilities
      • 🟰StringComparison
    • 🧰Debug Tools
      • 🧭Stopwatch
  • 🚀Razor
    • 🧱Configuración de Proyecto
    • 📃Pages
      • 🔸Método OnGet
      • 🔸Carpeta Models
      • 🔸Partial Pages
    • 🎨Layouts
      • Aplicar CSS A UNA PAGE
    • 🚴‍♂️Routing
    • 🏢_ViewImports
    • ✒️Sintaxis Razor
      • 😀Introducción
      • 📔Expresiones Implícitas
      • 📕Expresiones Explícitas
      • ✍️Renderizar Texto
      • 🧑‍🔬Class Page Model
      • 🔖Tag Helpers
        • 🔹asp-page
        • 🔹asp-append-version
        • 🔹asp-for
        • 🔹asp-items
        • 🔹asp-action y asp-controller
  • 🔮LUA
    • 🎯Fundamentos
    • ⌨️Entrada por Consola
    • 🔗Estructuras de Control
    • ⚒️Funciones
    • 📦Tablas
    • 📚Funciones y Librerías Estándar
    • 🦖POO
Con tecnología de GitBook
En esta página
  • 6.1. Simulación de Clases y Objetos 🏛️
  • 6.2. Herencia y Polimorfismo 🧬
  • 6.3. Encapsulamiento y Visibilidad de Miembros 🔒
  • 6.4. Uso de Metatables en la Programación Orientada a Objetos 🧩
  1. LUA

POO

LUA no tiene soporte nativo para la Programación Orientada a Objetos (POO), pero ofrece suficiente flexibilidad para implementarla utilizando tablas y metatables. En este tema, veremos cómo simular clases, objetos, herencia y otros conceptos clave de la POO en LUA.

6.1. Simulación de Clases y Objetos 🏛️

En LUA, se puede simular una clase usando una tabla. Los métodos de la clase se definen como funciones dentro de la tabla.

6.1.1. Creación de una clase

Para crear una clase, definimos una tabla y un constructor que inicialice sus propiedades.

-- Definimos la clase "Persona"
Persona = {}
Persona.__index = Persona

-- Constructor
function Persona:new(nombre, edad)
    local obj = {
        nombre = nombre or "Sin nombre",
        edad = edad or 0
    }
    setmetatable(obj, Persona)
    return obj
end

-- Método para mostrar información
function Persona:presentarse()
    print("Hola, soy " .. self.nombre .. " y tengo " .. self.edad .. " años.")
end

6.1.2. Creación de objetos

Usamos el constructor de la clase para crear instancias (objetos) de la clase.

-- Creamos un objeto de la clase Persona
local persona1 = Persona:new("Laura", 30)
persona1:presentarse()  -- Salida: Hola, soy Laura y tengo 30 años.

-- Creamos otro objeto con diferentes valores
local persona2 = Persona:new("Carlos", 25)
persona2:presentarse()  -- Salida: Hola, soy Carlos y tengo 25 años.

6.1.3. Añadir métodos adicionales

Podemos agregar más métodos a la clase para ampliar su funcionalidad.

-- Añadimos un método para cambiar el nombre
function Persona:cambiarNombre(nuevoNombre)
    self.nombre = nuevoNombre
end

-- Usamos el nuevo método
persona1:cambiarNombre("Ana")
persona1:presentarse()  -- Salida: Hola, soy Ana y tengo 30 años.

6.2. Herencia y Polimorfismo 🧬

La herencia en LUA se puede simular haciendo que una tabla "clase hija" tenga como metatable la "clase padre". Esto permite que la clase hija herede métodos y propiedades de la clase padre.

6.2.1. Creación de una subclase

Creamos una subclase Estudiante que herede de Persona.

-- Definimos la subclase "Estudiante"
Estudiante = Persona:new()
Estudiante.__index = Estudiante

-- Constructor de la subclase
function Estudiante:new(nombre, edad, carrera)
    local obj = Persona:new(nombre, edad)
    setmetatable(obj, Estudiante)
    obj.carrera = carrera or "Sin carrera"
    return obj
end

-- Método específico de Estudiante
function Estudiante:presentarse()
    print("Hola, soy " .. self.nombre .. ", tengo " .. self.edad .. " años, y estudio " .. self.carrera .. ".")
end

6.2.2. Uso de la subclase

Creamos un objeto de la subclase y usamos sus métodos.

local estudiante1 = Estudiante:new("María", 22, "Ingeniería")
estudiante1:presentarse()  -- Salida: Hola, soy María, tengo 22 años, y estudio Ingeniería.

6.2.3. Sobrescribir métodos

La subclase puede sobrescribir métodos de la clase padre para ofrecer un comportamiento especializado.

-- Método presentarse de Estudiante sobrescribe el de Persona
function Estudiante:presentarse()
    print("Soy " .. self.nombre .. ", estudio " .. self.carrera .. " y tengo " .. self.edad .. " años.")
end

-- Usamos el método sobrescrito
estudiante1:presentarse()  -- Salida: Soy María, estudio Ingeniería y tengo 22 años.

6.3. Encapsulamiento y Visibilidad de Miembros 🔒

En LUA, no existe un mecanismo nativo para definir la visibilidad de los miembros (públicos, privados, protegidos). Sin embargo, se pueden simular usando convenciones y closures.

6.3.1. Propiedades privadas con closures

Podemos simular propiedades privadas utilizando closures y funciones locales.

-- Definimos una clase con propiedades privadas
CuentaBancaria = {}
CuentaBancaria.__index = CuentaBancaria

function CuentaBancaria:new(saldoInicial)
    local saldo = saldoInicial or 0  -- Esta es una propiedad "privada"
    
    local obj = {}
    setmetatable(obj, CuentaBancaria)
    
    function obj:depositar(monto)
        saldo = saldo + monto
    end
    
    function obj:retirar(monto)
        if monto <= saldo then
            saldo = saldo - monto
        else
            print("Fondos insuficientes")
        end
    end
    
    function obj:consultarSaldo()
        return saldo
    end
    
    return obj
end

-- Usamos la clase con propiedades privadas
local cuenta = CuentaBancaria:new(100)
cuenta:depositar(50)
print("Saldo: " .. cuenta:consultarSaldo())  -- Salida: Saldo: 150
cuenta:retirar(20)
print("Saldo: " .. cuenta:consultarSaldo())  -- Salida: Saldo: 130

6.3.2. Métodos privados

También podemos definir métodos privados utilizando funciones locales dentro del constructor.

function CuentaBancaria:new(saldoInicial)
    local saldo = saldoInicial or 0

    local function calcularInteres()
        return saldo * 0.05
    end
    
    local obj = {}
    setmetatable(obj, CuentaBancaria)
    
    function obj:depositar(monto)
        saldo = saldo + monto + calcularInteres()
    end
    
    function obj:consultarSaldo()
        return saldo
    end
    
    return obj
end

-- Usamos el método privado
cuenta:depositar(100)
print("Saldo con interés: " .. cuenta:consultarSaldo())  -- Salida: Saldo con interés: 235

6.4. Uso de Metatables en la Programación Orientada a Objetos 🧩

Las metatables son un aspecto avanzado en LUA que se pueden usar para modificar el comportamiento de las tablas, permitiendo una implementación más flexible de la POO.

6.4.1. Sobrecarga de operadores

Podemos usar metatables para sobrecargar operadores, como sumar dos objetos.

-- Definimos la clase "Vector"
Vector = {}
Vector.__index = Vector

function Vector:new(x, y)
    local obj = {x = x, y = y}
    setmetatable(obj, Vector)
    return obj
end

-- Sobrecargamos el operador "+"
function Vector.__add(v1, v2)
    return Vector:new(v1.x + v2.x, v1.y + v2.y)
end

-- Usamos la sobrecarga de operadores
local v1 = Vector:new(2, 3)
local v2 = Vector:new(4, 5)
local v3 = v1 + v2
print("Resultado: (" .. v3.x .. ", " .. v3.y .. ")")  -- Salida: Resultado: (6, 8)

6.4.2. Métodos metamágicos útiles

Además de __add, LUA soporta otros métodos metamágicos para implementar diferentes comportamientos personalizados en las clases.

  • __tostring: Define cómo se muestra un objeto cuando se convierte en una cadena.

function Vector:__tostring()
    return "(" .. self.x .. ", " .. self.y .. ")"
end

-- Usamos __tostring
print(v3)  -- Salida: (6, 8)
  • __call: Permite que un objeto se comporte como una función.

function Vector:__call()
    return self.x, self.y
end

local x, y = v3()
print("Coordenadas: " .. x .. ", " .. y)  -- Salida: Coordenadas: 6, 8

Este bloque de código contiene todo el contenido del Tema 6 sobre la Programación Orientada a Objetos en LUA, en un formato que puedes copiar y pegar fácilmente. ¡Espero que te sea útil para avanzar en tu comprensión de LUA y la POO! 😊

AnteriorFunciones y Librerías Estándar

Última actualización hace 9 meses

🔮
🦖