Lua Orientada a Objetos
Avançado !
-
Lua é uma linguagem de programação(Sério??) , sua orientação a tabelas, meta tabelas, meta métodos é bem prático e versátil.
* Meta tabelas *
-
O que é uma meta tabelas?
- Exemplo, se colocar o código abaixo num interpretador Lua.
-
nome = "Xtibia Forum de Tibia"print(nome:upper())
A saída será:XTIBIA FORUM DE TIBIA
Porém, da onde saiu esse upper()? Vejamos..print(getmetatable(nome))
Sua saída será:table: 0033BE78
Uma meta tabela associado a string !!, vejamos:print(getmetatable(nome).__index == string)
Sua saída será:true
ou seja concluímos que a chave __index da meta tabelas é módulo de uma string: como exemplonome:upper() == nome.upper(nome) == string.upper(nome)
*Chave __index*
-
A chave __index da meta tabela pode ser uma tabela ou uma função e indica o que deve acontecer quando houver uma tentativa de leitura de uma chave que a estrutura de dados original não possuía
Se o objeto referenciado pela variável nome(uma string) não possui a chave upper, então quando tentamos acessar esta chave, o sistema procura pela chave na tabela referenciada pela chave __index da meta tabela, que é uma string - Caso queiramos que ela retorna um valor da tabela ASCII, podemos utilizar está função
mt = {__index = function (t, k)return k:byte()end}var = setmetatable({b}, mt)print(var)
Vale lembrar que essa chave é importante para orientação a objetos.
* Classes e Construtores *
- Em orientação a objeto, classe é um molde para a criação de novos objetos, em Lua,classe em geral é uma meta tabela onde a chave __index aponta para ela própria.
-
Exemplo abaixo:
mt = {}mt.__index = mt
Meta tabelas se torna um molde para as outras tabelas. As tabelas que fazem o uso deste molde são chamadas de instâncias.
As funções de uma classe/instância são chamadas de métodos e sempre recebem implícita ou explicitamente como primeiro argumento a classe ou instância que faz a chamada.
Lua pode chamar um método passando a instância (ou classe) implícita ou explicitamente -
Exemplo de uma chamada explícita:
login = login.lower(login)
-
Exemplo de uma chamada , passando a instância implicitamente
login = login:lower()
Existe um método especial chamado construtor, que é executado sempre que uma nova instância é criada. -
Vejamos:
function mt:new(o)o = o or {}return setmetatable(o, self)end
O construtor do código a cima recebe como um argumento uma tabela que servirá de referência para a criação da instância.
O primeiro comando garante que o argumento o é uma tabela, o segundo associa a meta tabela ao objeto, retornando-o.
Como new()é um método de classe, self representa a classe. Se fosse um método de instância, self representaria a instância.
* Outros métodos *
- Podemos criar outros métodos. Por exemplo queremos criar um somatório dos elementos números da tabela seja retornado para o método soma()
- Exemplo
function mt:soma()local s = 0table.foreachi(self, function (i, e)if type(e) == "number" thens = s + eendend)return send
Podemos criar um objeto com alguns valores números e retornar seu somatório:var = mt:new { 2, 4, 6 }ret = var:soma()print (ret)
Que imprimirá:12
*Meta Métodos*
Apenas irei citar alguns, caso tenha curiosidade procure sobre.
- __add – gerencia operador de adição;
- __sub – gerencia operador de subtração;
- __mul – gerencia operador de multiplicação;
- __div – gerencia operador de divisão;
- __unm – gerencia operador unário de negação;
- __eq – gerencia operador de igualdade;
- __lt – gerencia operadores menor que e igual ou maior;
- __le – gerencia operadores menor ou igual e maior que;
- __pow – gerencia operador de potência;
- __tostring – gerencia conversão para string;
- __tonumber – gerencia conversão para número.
* Herança *
-
Queremos outra classe que além de devolver a soma, também devolva o produto, mas sem modificar a classe original.
Para isso herdamos uma nova classe, para isso precisamos instanciar a classe pai normalmente, modificar a instância e usar esta instância como uma nova classe -
Exemplo
function nmt:produto()local p = 1]table.foreachi(self, function (i, e)if type(e) == "number" thenp = p * eendend)return pendvar = nmt:new { 2, 4, 6 }[size=4]print(var:soma(), var:produto())
Imprimirá:48
Há outra forma mais avançada de herança, chamada herança múltipla, que acontece quando uma classe é herdeira de mais de uma classe pai.Fim.
Mega Tutorial OOP em Lua