Lua物件導向程式設計


物件導向程式設計(OOP)是現代程式設計中使用最多的程式設計技術之一。 有許多支援OOP的程式設計語言套件括 -

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

物件導向的特點

  • - 類是用於建立物件的可延伸模板,為狀態(成員變數)和行為實現提供初始值。
  • 物件 - 它是類的一個範例,並為自己分配了單獨的記憶體。
  • 繼承 - 這是一個概念,通過該概念,一個類的變數和函式由另一個類繼承。
  • 封裝 - 這是在類中組合資料和函式的過程。借助函式可以在類的外部存取資料。 它也被稱為資料抽象。

Lua物件導向

可使用Lua的表和第一類函式在Lua中實現物件導向。 通過將函式和相關資料放入表中,形成物件。可使用元表實現繼承,為父物件中不存在的函式(方法)和欄位提供查詢機制。

Lua中的表具有狀態和標識等物件的特徵,與其值無關。 具有相同值的兩個物件(表)是不同的物件,而物件在不同的時間可以具有不同的值,但它始終是相同的物件。 與物件一樣,表的生命週期與誰建立它們或建立位置無關。

真實世界的例子

物件導向的概念廣泛使用,但需要清楚地理解物件導向以獲得適當和最大的好處。
考慮一個簡單的數學例子。 我們經常遇到處理不同形狀的情況,如圓形,矩形和方形。

形狀可以具有共同的屬性area。 因此,使用公共屬性區域從基礎物件形狀擴充套件其他形狀。 每個形狀都可以有自己的屬性,像矩形這樣的函式可以具有屬性lengthwidtharea作為屬性,printAreacalculateArea作為它的函式。

建立一個簡單的類

下面顯示了具有三個屬性lengthwidtharea的矩形的簡單類實現。 它還有一個printArea函式來列印計算區域面積。

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

建立一個物件
建立物件是為類範例分配記憶體的過程。 每個物件都有自己的記憶體並共用公共類資料。

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

存取屬性
可以使用點(.)運算子存取類中的屬性,如下所示 -

print(r.length)

存取成員函式

使用帶有物件的冒號(:)運算子存取成員函式,如下所示 -

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

分配記憶體並設定初始值。可以將初始化過程與其他物件導向語言中的建構函式進行比較。 它只是一個能夠設定如上所示的值的函式。

完整的例子
下面來看一下在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()

執行上述程式時,將獲得以下輸出 -

The area is     100

Lua繼承

繼承是將簡單的基礎物件(如形狀)擴充套件為矩形,正方形等的過程。 它經常在現實世界中用於共用和擴充套件基本屬性和功能。

下面來看一個簡單的類擴充套件。有一個如下所示的類,

-- 元類
Shape = {area = 0}

-- 基礎類別方法
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

-- 基礎類別方法 - printArea

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

可以將形狀擴充套件為方形類,如下所示。

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

繼承完整範例
在另一個new方法的幫助下,使用metatables,擴充套件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()

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

當執行上述程式時,將獲得以下輸出 -

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

在上面的例子中,建立了兩個派生類 - 基礎類別SquareRectangle。並在派生類中覆蓋基礎類別的函式。 在此範例中,派生類會覆蓋函式printArea