English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Orientação a Objetos no Lua

Programação orientada a objetos (Object Oriented Programming, OOP) é uma arquitetura de programação de computadores muito popular.

Os seguintes tipos de linguagens de programação suportam programação orientada a objetos:

  • C++

  • Java

  • Objective-C

  • Smalltalk

  • C#

  • Ruby

Características orientadas a objetos

  • 1Encapsulamento: Refere-se à capacidade de encapsular as informações, funcionalidades e respostas de um entidade em um único objeto.

  • 2Herança: O método de herança permite expandir o programa sem alterá-lo, mantendo assim as funcionalidades originais e expandindo novas funcionalidades. Isso é benéfico para reduzir a repetição de código e aumentar a eficiência do desenvolvimento de software.

  • 3Polimorfismo: A mesma operação aplicada a diferentes objetos pode ter diferentes interpretações, resultando em diferentes resultados de execução. Durante a execução, pode-se chamar métodos de classes derivadas através de ponteiros para a classe base.

  • 4Abstract: A abstração (Abstração) é uma maneira de simplificar problemas complexos da realidade, permitindo encontrar a definição de classe mais apropriada para problemas específicos e explicando problemas no nível de herança mais apropriado.

Programação orientada a objetos no Lua

Sabemos que os objetos são compostos por atributos e métodos. A estrutura mais básica do LUA é a tabela, então é necessário usar a tabela para descrever os atributos do objeto.

A função no Lua pode ser usada para representar métodos. Portanto, a classe no LUA pode ser representada por tabela + function simulada.

Em relação à herança, pode ser simulada através da metatable (não recomendado, apenas para simular os objetos mais básicos, que geralmente são suficientes).

As table no Lua não apenas é uma espécie de objeto. Como objeto, a tabela também possui estado (variáveis de membro); também possui uma natureza independente dos valores do objeto, especialmente quando dois objetos (tabela) representam dois objetos diferentes com valores diferentes; um objeto pode ter diferentes valores em diferentes momentos, mas ele sempre é um objeto; semelhante ao objeto, o ciclo de vida da tabela não tem relação com o que a criou ou onde foi criada. Os objetos têm seus membros funções, e as tabelas também:

Account = {saldo = 0}
function Account:withdraw(v)
    Account.saldo = Account.saldo - v
fim

Esta definição cria uma nova função e armazena dentro do domínio da instância da Account, a seguir podemos chamá-la assim:

Account.withdraw(100,00)

um exemplo simples

A seguir, uma classe simples contém três propriedades: area, comprimento e largura, o método printArea é usado para imprimir o resultado da calculação:

-- metaclasse
Rectangle = {area = 0, comprimento = 0, largura = 0}
-- método new da classe derivada
function Rectangle:new (o, comprimento, largura)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  self.comprimento = comprimento or 0
  self.largura = largura or 0
  self.area = comprimento*largura;
  retorna o
fim
-- método printArea da classe derivada
function Rectangle:printArea ()
  print("Área do retângulo", self.area)
fim

Criação de objetos

A criação do objeto é o processo de alocação de memória para o exemplo da classe. Cada classe possui sua própria memória e compartilha dados comuns.

r = Rectangle:new(nil,10,20)

Acessar propriedade

Podemos usar o ponto . para acessar as propriedades da classe:

print(r.comprimento)

Acessar função membro

Podemos usar dois pontos : para acessar as funções membros da classe:

r:printArea()

A memória é alocada no inicialização do objeto.

exemplo completo

A seguir, mostramos um exemplo completo de orientação a objetos Lua:

-- metaclasse
Shape = {area = 0}
-- método básico new
function Shape:new(o, lado)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  lado = lado or 0
  self.area = lado*lado;
  retorna o
fim
-- método básico printArea
function Shape:printArea()
  print("Área", self.area)
fim
-- Criação de objetos
myshape = Shape:new(nil,10)
myshape:printArea()

Ao executar o programa acima, o resultado de saída é:

Área é     100

Herança Lua

Herança é o uso direto das propriedades e métodos de outro objeto. Pode ser usado para expandir as propriedades e métodos da classe básica.

A seguir, é demonstrado um exemplo simples de herança:

-- classe meta
Shape = {area = 0}
-- método básico new
function Shape:new(o, lado)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  lado = lado or 0
  self.area = lado*lado;
  retorna o
fim
-- método básico printArea
function Shape:printArea()
  print("Área", self.area)
fim

No próximo exemplo, o objeto Square herda a classe Shape:

Square = Shape:new()
-- método da classe derivada new
function Square:new (o, lado)
  o = o ou Shape:new(o, lado)
  setmetatable(o, self)
  self.__index = self
  retorna o
fim

exemplo completo

A seguir, mostramos um exemplo de herança de uma classe simples para expandir os métodos da classe derivada, a classe derivada mantém os membros variáveis e métodos da classe herdada:

-- classe meta
Shape = {area = 0}
-- método básico new
function Shape:new(o, lado)
  o = o or {}
  setmetatable(o, self)
  self.__index = self
  lado = lado or 0
  self.area = lado*lado;
  retorna o
fim
-- método básico printArea
function Shape:printArea()
  print("Área", self.area)
fim
-- Criação de objetos
myshape = Shape:new(nil,10)
myshape:printArea()
Square = Shape:new()
-- Método da classe derivada new
function Square:new (o, lado)
  o = o ou Shape:new(o, lado)
  setmetatable(o, self)
  self.__index = self
  retorna o
fim
-- Método da classe derivada printArea
function Square:printArea ()
  print("Área do quadrado", self.area)
fim
-- Criação de objetos
mysquare = Square:new(nil,10)
mysquare:printArea()
Rectangle = Shape:new()
-- Método da classe derivada new
function Rectangle:new (o, comprimento, largura)
  o = o ou Shape:new(o)
  setmetatable(o, self)
  self.__index = self
  self.area = comprimento * largura
  retorna o
fim
-- Método da classe derivada printArea
function Rectangle:printArea ()
  print("Área do retângulo", self.area)
fim
-- Criação de objetos
myrectangle = Rectangle:new(nil,10,20)
myrectangle:printArea()

Executando o código acima, o resultado será:

Área é     100
Área do quadrado é     100
Área do retângulo é     200

Sobrescrita de Função

No Lua, podemos sobrescrever funções da classe base, definindo nossa própria implementação nas classes derivadas:

-- Método da classe derivada printArea
function Square:printArea ()
  print("Área do quadrado", self.area)
fim