Lua - Objektorientiert

Einführung in OOP

Die objektorientierte Programmierung (OOP) ist eine der am häufigsten verwendeten Programmiertechniken, die in der modernen Programmierzeit verwendet werden. Es gibt eine Reihe von Programmiersprachen, die OOP unterstützen, darunter:

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

Merkmale von OOP

  • Class - Eine Klasse ist eine erweiterbare Vorlage zum Erstellen von Objekten, die Anfangswerte für den Status (Elementvariablen) und Verhaltensimplementierungen bereitstellt.

  • Objects - Es ist eine Instanz der Klasse und hat einen separaten Speicher für sich.

  • Inheritance - Es ist ein Konzept, nach dem Variablen und Funktionen einer Klasse von einer anderen Klasse geerbt werden.

  • Encapsulation- Es ist der Prozess des Kombinierens der Daten und Funktionen innerhalb einer Klasse. Auf Daten kann außerhalb der Klasse mit Hilfe von Funktionen zugegriffen werden. Es wird auch als Datenabstraktion bezeichnet.

OOP in Lua

Sie können die Objektorientierung in Lua mithilfe von Tabellen und erstklassigen Funktionen von Lua implementieren. Durch Platzieren von Funktionen und zugehörigen Daten in einer Tabelle wird ein Objekt gebildet. Die Vererbung kann mithilfe von Metatabellen implementiert werden und bietet einen Suchmechanismus für nicht vorhandene Funktionen (Methoden) und Felder in übergeordneten Objekten.

Tabellen in Lua haben die Merkmale von Objekten wie Zustand und Identität, die unabhängig von ihren Werten sind. Zwei Objekte (Tabellen) mit demselben Wert sind unterschiedliche Objekte, während ein Objekt zu unterschiedlichen Zeiten unterschiedliche Werte haben kann, aber immer dasselbe Objekt ist. Wie Objekte haben Tabellen einen Lebenszyklus, der unabhängig davon ist, wer sie erstellt hat oder wo sie erstellt wurden.

Ein Beispiel aus der realen Welt

Das Konzept der Objektorientierung ist weit verbreitet, aber Sie müssen es klar verstehen, um einen angemessenen und maximalen Nutzen zu erzielen.

Betrachten wir ein einfaches mathematisches Beispiel. Wir begegnen oft Situationen, in denen wir an verschiedenen Formen wie Kreis, Rechteck und Quadrat arbeiten.

Die Formen können einen gemeinsamen Eigenschaftsbereich haben. So können wir andere Formen von der Basisobjektform mit dem gemeinsamen Eigenschaftsbereich erweitern. Jede der Formen kann ihre eigenen Eigenschaften und Funktionen haben, wie ein Rechteck Eigenschaften wie Länge, Breite, Fläche als Eigenschaften und printArea und berechneArea als seine Funktionen haben kann.

Erstellen einer einfachen Klasse

Eine einfache Klassenimplementierung für ein Rechteck mit drei Eigenschaften, Bereich, Länge und Breite, wird unten gezeigt. Es hat auch eine printArea-Funktion zum Drucken der berechneten Fläche.

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

Ein Objekt erstellen

Beim Erstellen eines Objekts wird Speicher für die Klasseninstanz zugewiesen. Jedes der Objekte verfügt über einen eigenen Speicher und teilt die gemeinsamen Klassendaten.

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

Zugriff auf Eigenschaften

Wir können mit dem Punktoperator wie unten gezeigt auf die Eigenschaften in der Klasse zugreifen -

print(r.length)

Zugriff auf die Mitgliedsfunktion

Sie können auf eine Elementfunktion zugreifen, indem Sie den Doppelpunktoperator mit dem Objekt wie unten gezeigt verwenden.

r:printArea()

Der Speicher wird zugewiesen und die Anfangswerte werden festgelegt. Der Initialisierungsprozess kann mit Konstruktoren in anderen objektorientierten Sprachen verglichen werden. Es ist nichts anderes als eine Funktion, mit der Werte wie oben gezeigt eingestellt werden können.

Vollständiges Beispiel

Schauen wir uns ein vollständiges Beispiel mit Objektorientierung in Lua an.

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

Wenn Sie das obige Programm ausführen, erhalten Sie die folgende Ausgabe.

The area is 	100

Vererbung in Lua

Bei der Vererbung werden einfache Basisobjekte wie die Form auf Rechtecke, Quadrate usw. erweitert. In der realen Welt wird es häufig verwendet, um die grundlegenden Eigenschaften und Funktionen zu teilen und zu erweitern.

Lassen Sie uns eine einfache Klassenerweiterung sehen. Wir haben eine Klasse wie unten gezeigt.

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

Wir können die Form wie unten gezeigt auf eine quadratische Klasse erweitern.

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

Übergeordnete Basisfunktionen

Wir können die Basisklassenfunktionen überschreiben, dh anstatt die Funktion in der Basisklasse zu verwenden, kann die abgeleitete Klasse eine eigene Implementierung haben, wie unten gezeigt -

-- Derived class method printArea

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

Vererbung vollständiges Beispiel

Wir können die einfache Klassenimplementierung in Lua wie oben gezeigt mit Hilfe einer anderen neuen Methode mit Hilfe von Metatabellen erweitern. Alle Mitgliedsvariablen und Funktionen der Basisklasse bleiben in der abgeleiteten Klasse erhalten.

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

Wenn wir das obige Programm ausführen, erhalten wir die folgende Ausgabe:

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

Im obigen Beispiel haben wir zwei abgeleitete Klassen erstellt - Rechteck und Quadrat aus der Basisklasse Quadrat. Es ist möglich, die Funktionen der Basisklasse in der abgeleiteten Klasse zu überschreiben. In diesem Beispiel überschreibt die abgeleitete Klasse die Funktion printArea.