Buscar..


Introducción

Lua en sí no ofrece ningún sistema de clase. Sin embargo, es posible implementar clases y objetos como tablas con solo algunos trucos.

Sintaxis

  • function <class>.new() return setmetatable({}, {__index=<class>}) end

Orientación a objetos simples

Aquí hay un ejemplo básico de cómo hacer un sistema de clases muy simple.

Class = {}
local __instance = {__index=Class} -- Metatable for instances
function Class.new()
    local instance = {}
    setmetatable(instance, __instance)
    return instance
-- equivalent to: return setmetatable({}, __instance)
end

Para agregar variables y / o métodos, simplemente agréguelos a la clase. Ambos pueden ser anulados para cada instancia.

Class.x = 0
Class.y = 0
Class:getPosition()
    return {self.x, self.y}
end

Y para crear una instancia de la clase:

object = Class.new()

o

setmetatable(Class, {__call = Class.new}
    -- Allow the class itself to be called like a function
object = Class()

Y para usarlo:

object.x = 20
-- This adds the variable x to the object without changing the x of
-- the class or any other instance. Now that the object has an x, it
-- will override the x that is inherited from the class
print(object.x)
-- This prints 20 as one would expect.
print(object.y)
-- Object has no member y, therefore the metatable redirects to the
-- class table, which has y=0; therefore this prints 0
object:getPosition() -- returns {20, 0}

Cambio de metamétodos de un objeto.

Teniendo

local Class = {}
Class.__meta = {__index=Class}
function Class.new() return setmetatable({}, Class.__meta)

Suponiendo que queremos cambiar el comportamiento de un solo object = Class.new() instancia object = Class.new() usando un metatable,

Hay algunos errores para evitar:

setmetatable(object, {__call = table.concat}) -- WRONG

Esto intercambia el antiguo metatable con el nuevo, rompiendo así la herencia de clase.

getmetatable(object).__call = table.concat -- WRONG AGAIN

Tenga en cuenta que los "valores" de la tabla son solo una referencia; de hecho, solo hay una tabla real para todas las instancias de un objeto, a menos que el constructor se defina como en 1 , por lo que al modificar el comportamiento de todas las instancias de la clase.


Una forma correcta de hacer esto:

Sin cambiar la clase:

setmetatable(
    object,
    setmetatable(
        {__call=table.concat},
        {__index=getmetatable(object)}
    )
)

¿Como funciona esto? - Creamos un nuevo metatable como en el error # 1, pero en lugar de dejarlo vacío, creamos una copia en papel del metatable original. Se podría decir que el nuevo metatable "hereda" del original como si fuera una instancia de clase. Ahora podemos anular los valores del metatable original sin modificarlos.

Cambiando la clase:

1º (recomendado):

local __instance_meta = {__index = Class.__meta}
-- metatable for the metatable
-- As you can see, lua can get very meta very fast
function Class.new()
    return setmetatable({}, setmetatable({}, __instance_meta))
end

2º (menos recomendado): ver 1


1 function Class.new() return setmetatable({}, {__index=Class}) end



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow