Lua - Orientada a Objetos

Introdução ao OOP

A Programação Orientada a Objetos (OOP), é uma das técnicas de programação mais usadas na era moderna da programação. Existem várias linguagens de programação que suportam OOP, que incluem,

  • C++
  • Java
  • Objective-C
  • Smalltalk
  • C#
  • Ruby

Características do OOP

  • Class - Uma classe é um modelo extensível para criar objetos, fornecendo valores iniciais para o estado (variáveis ​​de membro) e implementações de comportamento.

  • Objects - É uma instância de classe e tem memória separada alocada para si mesma.

  • Inheritance - É um conceito pelo qual as variáveis ​​e funções de uma classe são herdadas por outra classe.

  • Encapsulation- É o processo de combinar os dados e funções dentro de uma classe. Os dados podem ser acessados ​​fora da classe com a ajuda de funções. Também é conhecido como abstração de dados.

OOP em Lua

Você pode implementar orientação a objetos em Lua com a ajuda de tabelas e funções de primeira classe de Lua. Ao colocar funções e dados relacionados em uma tabela, um objeto é formado. A herança pode ser implementada com a ajuda de meta-tabelas, fornecendo um mecanismo de pesquisa para funções (métodos) e campos inexistentes em objeto (s) pai (s).

As tabelas em Lua possuem características de objeto como estado e identidade que são independentes de seus valores. Dois objetos (tabelas) com o mesmo valor são objetos diferentes, enquanto um objeto pode ter valores diferentes em momentos diferentes, mas é sempre o mesmo objeto. Assim como os objetos, as tabelas têm um ciclo de vida independente de quem as criou ou de onde foram criadas.

Um exemplo do mundo real

O conceito de orientação a objetos é amplamente utilizado, mas você precisa entendê-lo claramente para obter o máximo benefício.

Vamos considerar um exemplo simples de matemática. Freqüentemente encontramos situações em que trabalhamos em diferentes formas, como círculo, retângulo e quadrado.

As formas podem ter uma área de propriedade comum. Portanto, podemos estender outras formas da forma do objeto base com a área de propriedade comum. Cada uma das formas pode ter suas próprias propriedades e funções, como um retângulo pode ter propriedades comprimento, largura, área como suas propriedades e printArea e calculArea como suas funções.

Criação de uma classe simples

Uma implementação de classe simples para um retângulo com três propriedades: área, comprimento e largura é mostrada abaixo. Também possui uma função printArea para imprimir a área calculada.

-- Meta class
Rectangle = {area = 0, length = 0, breadth = 0}

-- Derived class method new

function Rectangle:new (o,length,breadth)
   o = o or {}
   setmetatable(o, self)
   self.__index = self
   self.length = length or 0
   self.breadth = breadth or 0
   self.area = length*breadth;
   return o
end

-- Derived class method printArea

function Rectangle:printArea ()
   print("The area of Rectangle is ",self.area)
end

Criação de um objeto

Criar um objeto é o processo de alocar memória para a instância da classe. Cada um dos objetos possui sua própria memória e compartilha os dados de classe comuns.

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

Acessando Propriedades

Podemos acessar as propriedades da classe usando o operador ponto, conforme mostrado abaixo -

print(r.length)

Acessando Função de Membro

Você pode acessar uma função de membro usando o operador de dois pontos com o objeto conforme mostrado abaixo -

r:printArea()

A memória é alocada e os valores iniciais são definidos. O processo de inicialização pode ser comparado aos construtores em outras linguagens orientadas a objetos. Não é nada além de uma função que permite definir valores conforme mostrado acima.

Exemplo Completo

Vamos ver um exemplo completo usando orientação a objetos em Lua.

-- Meta class
Shape = {area = 0}

-- Base class method new

function Shape:new (o,side)
   o = o or {}
   setmetatable(o, self)
   self.__index = self
   side = side or 0
   self.area = side*side;
   return o
end

-- Base class method printArea

function Shape:printArea ()
   print("The area is ",self.area)
end

-- Creating an object
myshape = Shape:new(nil,10)

myshape:printArea()

Ao executar o programa acima, você obterá a seguinte saída.

The area is 	100

Herança em Lua

Herança é o processo de estender objetos básicos simples, como forma, a retângulos, quadrados e assim por diante. É freqüentemente usado no mundo real para compartilhar e estender as propriedades e funções básicas.

Vamos ver uma extensão de classe simples. Temos uma aula conforme mostrado abaixo.

-- Meta class
Shape = {area = 0}

-- Base class method new

function Shape:new (o,side)
   o = o or {}
   setmetatable(o, self)
   self.__index = self
   side = side or 0
   self.area = side*side;
   return o
end

-- Base class method printArea

function Shape:printArea ()
   print("The area is ",self.area)
end

Podemos estender a forma para uma classe quadrada, conforme mostrado abaixo.

Square = Shape:new()

-- Derived class method new

function Square:new (o,side)
   o = o or Shape:new(o,side)
   setmetatable(o, self)
   self.__index = self
   return o
end

Funções básicas de sobreposição

Podemos substituir as funções da classe base que, em vez de usar a função na classe base, a classe derivada pode ter sua própria implementação, conforme mostrado abaixo -

-- Derived class method printArea

function Square:printArea ()
   print("The area of square is ",self.area)
end

Exemplo completo de herança

Podemos estender a implementação de classe simples em Lua como mostrado acima com a ajuda de outro novo método com a ajuda de meta-tabelas. Todas as variáveis ​​de membro e funções da classe base são retidas na classe derivada.

-- Meta class
Shape = {area = 0}

-- Base class method new

function Shape:new (o,side)
   o = o or {}
   setmetatable(o, self)
   self.__index = self
   side = side or 0
   self.area = side*side;
   return o
end

-- Base class method printArea

function Shape:printArea ()
   print("The area is ",self.area)
end

-- Creating an object
myshape = Shape:new(nil,10)
myshape:printArea()

Square = Shape:new()

-- Derived class method new

function Square:new (o,side)
   o = o or Shape:new(o,side)
   setmetatable(o, self)
   self.__index = self
   return o
end

-- Derived class method printArea

function Square:printArea ()
   print("The area of square is ",self.area)
end

-- Creating an object
mysquare = Square:new(nil,10)
mysquare:printArea()

Rectangle = Shape:new()

-- Derived class method new

function Rectangle:new (o,length,breadth)
   o = o or Shape:new(o)
   setmetatable(o, self)
   self.__index = self
   self.area = length * breadth
   return o
end

-- Derived class method printArea

function Rectangle:printArea ()
    print("The area of Rectangle is ",self.area)
end

-- Creating an object

myrectangle = Rectangle:new(nil,10,20)
myrectangle:printArea()

Quando executarmos o programa acima, obteremos a seguinte saída -

The area is 	100
The area of square is 	100
The area of Rectangle is 	200

No exemplo acima, criamos duas classes derivadas - Retângulo e Quadrado a partir da classe base Quadrado. É possível substituir as funções da classe base na classe derivada. Neste exemplo, a classe derivada substitui a função printArea.