Lua - Orienté objet

Introduction à la POO

La programmation orientée objet (POO) est l'une des techniques de programmation les plus utilisées à l'ère moderne de la programmation. Il existe un certain nombre de langages de programmation prenant en charge la POO, notamment:

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

Caractéristiques de la POO

  • Class - Une classe est un modèle extensible pour créer des objets, fournissant des valeurs initiales pour l'état (variables membres) et les implémentations de comportement.

  • Objects - C'est une instance de classe et a une mémoire séparée allouée pour elle-même.

  • Inheritance - C'est un concept par lequel les variables et les fonctions d'une classe sont héritées par une autre classe.

  • Encapsulation- C'est le processus de combinaison des données et des fonctions à l'intérieur d'une classe. Les données sont accessibles en dehors de la classe à l'aide de fonctions. Il est également connu sous le nom d'abstraction de données.

POO à Lua

Vous pouvez implémenter l'orientation objet dans Lua à l'aide de tables et de fonctions de première classe de Lua. En plaçant des fonctions et des données associées dans une table, un objet est formé. L'héritage peut être implémenté à l'aide de métatables, fournissant un mécanisme de recherche pour les fonctions (méthodes) et les champs inexistants dans les objets parents.

Les tables dans Lua ont les caractéristiques d'objet comme l'état et l'identité qui sont indépendantes de ses valeurs. Deux objets (tables) avec la même valeur sont des objets différents, alors qu'un objet peut avoir des valeurs différentes à des moments différents, mais c'est toujours le même objet. Tout comme les objets, les tables ont un cycle de vie indépendant de la personne qui les a créées ou de l'endroit où elles ont été créées.

Un exemple du monde réel

Le concept d'orientation objet est largement utilisé, mais vous devez le comprendre clairement pour un bénéfice approprié et maximal.

Prenons un exemple mathématique simple. Nous rencontrons souvent des situations où nous travaillons sur différentes formes comme le cercle, le rectangle et le carré.

Les formes peuvent avoir une propriété commune. Ainsi, nous pouvons étendre d'autres formes à partir de la forme de l'objet de base avec la zone de propriété commune. Chacune des formes peut avoir ses propres propriétés et des fonctions comme un rectangle peut avoir des propriétés length, width, area comme propriétés et printArea et CalculateArea comme fonctions.

Créer une classe simple

Une implémentation de classe simple pour un rectangle avec trois propriétés area, length et width est illustrée ci-dessous. Il dispose également d'une fonction printArea pour imprimer la zone calculée.

-- 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

Créer un objet

La création d'un objet est le processus d'allocation de mémoire pour l'instance de classe. Chacun des objets a sa propre mémoire et partage les données de classe communes.

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

Accéder aux propriétés

Nous pouvons accéder aux propriétés de la classe en utilisant l'opérateur point comme indiqué ci-dessous -

print(r.length)

Accès à la fonction membre

Vous pouvez accéder à une fonction membre en utilisant l'opérateur deux-points avec l'objet comme indiqué ci-dessous -

r:printArea()

La mémoire est allouée et les valeurs initiales sont définies. Le processus d'initialisation peut être comparé aux constructeurs dans d'autres langages orientés objet. Ce n'est rien d'autre qu'une fonction qui permet de définir des valeurs comme indiqué ci-dessus.

Exemple complet

Regardons un exemple complet utilisant l'orientation objet dans 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()

Lorsque vous exécutez le programme ci-dessus, vous obtiendrez la sortie suivante.

The area is 	100

Héritage à Lua

L'héritage est le processus consistant à étendre des objets de base simples comme la forme à des rectangles, des carrés, etc. Il est souvent utilisé dans le monde réel pour partager et étendre les propriétés et fonctions de base.

Voyons une simple extension de classe. Nous avons une classe comme indiqué ci-dessous.

-- 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

Nous pouvons étendre la forme à une classe carrée comme indiqué ci-dessous.

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

Fonctions de base de dépassement

Nous pouvons remplacer les fonctions de classe de base qui sont au lieu d'utiliser la fonction dans la classe de base, la classe dérivée peut avoir sa propre implémentation comme indiqué ci-dessous -

-- Derived class method printArea

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

Exemple d'héritage complet

Nous pouvons étendre l'implémentation de classe simple dans Lua comme indiqué ci-dessus à l'aide d'une autre nouvelle méthode à l'aide de métatables. Toutes les variables membres et fonctions de la classe de base sont conservées dans la classe dérivée.

-- 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()

Lorsque nous exécutons le programme ci-dessus, nous obtiendrons la sortie suivante -

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

Dans l'exemple ci-dessus, nous avons créé deux classes dérivées - Rectangle et Square à partir de la classe de base Square. Il est possible de remplacer les fonctions de la classe de base dans la classe dérivée. Dans cet exemple, la classe dérivée remplace la fonction printArea.