One important thing to remember is that lun is not object oriented. There are no actual classes.
Moon works more like JavaScript's "object orientation" (older versions of it at least), where you move the ".prototype" of the object.
But Moon is flexible to the point of being able to "simulate" object orientation with some of its constructs.
You can start by defining your "class" (which, remember, is an object itself. There are no classes).
local Quadrado = {}
Quadrado.__index = Quadrado
The first line simply creates an empty table. Then we'll put some attributes and methods in it. The important thing here is the second line. The __index
passes all indexes ( Classe[x]
, Classe.x
) to the table itself. This will make sense in the next block of code.
Now, let's define a constructor:
function Quadrado:novoQuadrado(tamanhoLado)
return setmetatable({lado = tamanhoLado}, Quadrado)
end
The magic is done in setmetatable
. Note that I'm returning a new table with a side attribute ( {lado = tamanhoLado}
, and passing my definition of Square as its metatable.
A metatable is a way to change the behavior of a table. A good example of this is to define two tables, a
and b
, and try to sum them a + b
. Moon does not know how to do this, but she will look at those metatables from the tables. If any of them has a method at the __add
index, then Lua will use this method to do the sum (something like a:__add(b)
).
Remember the __index
we changed up there? It's the same scheme. We are sending our Square to look for indexes in the Square itself. When we use a Quadrado.area
, which we will define shortly, Lua will look for this index (or attribute, or field) in the Quadrado
table, and find Quadrado.area
. It makes no sense? But remember that we passed the Quadrado as a metatable? Then all the objects we create will use Square as a metatable, and will search their indexes in the same way (% with%). I do not know if you can understand what I mean: (
To define a method, we can use the following syntax:
function Quadrado:area()
return self.lado * self.lado
end
This Quadrado.area
syntax is just syntatic sugar for
function Quadrado.area(self)
Now just use our "class":
local q = Quadrado:novoQuadrado(10)
print(q:area()) -- 100
The Quadrado:area
is syntatic sugar for q:area
(remember that we changed the metatable? This is using the square area). I still do not know if you could understand, but that's it.
So, answering your questions:
- No, there is no constructor because there is no class. What exists is the function that we have agreed as a constructor (
q.area(q)
).
- The method is declared with the change in the metatable.
- It is important to note that we are using two "objects" (two tables,
Quadrado:novoQuadrado
and Quadrado
), not a class and an object.
Of course, I have not studied Lua for some time, and I do not know if there are evolutions in this scheme. But in my day it was like this.