物件導向程式設計(OOP)是現代程式設計中使用最多的程式設計技術之一。 有許多支援OOP的程式設計語言套件括 -
可使用Lua的表和第一類函式在Lua中實現物件導向。 通過將函式和相關資料放入表中,形成物件。可使用元表實現繼承,為父物件中不存在的函式(方法)和欄位提供查詢機制。
Lua中的表具有狀態和標識等物件的特徵,與其值無關。 具有相同值的兩個物件(表)是不同的物件,而物件在不同的時間可以具有不同的值,但它始終是相同的物件。 與物件一樣,表的生命週期與誰建立它們或建立位置無關。
物件導向的概念廣泛使用,但需要清楚地理解物件導向以獲得適當和最大的好處。
考慮一個簡單的數學例子。 我們經常遇到處理不同形狀的情況,如圓形,矩形和方形。
形狀可以具有共同的屬性area
。 因此,使用公共屬性區域從基礎物件形狀擴充套件其他形狀。 每個形狀都可以有自己的屬性,像矩形這樣的函式可以具有屬性length
,width
,area
作為屬性,printArea
和calculateArea
作為它的函式。
下面顯示了具有三個屬性length
,width
和area
的矩形的簡單類實現。 它還有一個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
繼承是將簡單的基礎物件(如形狀)擴充套件為矩形,正方形等的過程。 它經常在現實世界中用於共用和擴充套件基本屬性和功能。
下面來看一個簡單的類擴充套件。有一個如下所示的類,
-- 元類
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
在上面的例子中,建立了兩個派生類 - 基礎類別Square
和Rectangle
。並在派生類中覆蓋基礎類別的函式。 在此範例中,派生類會覆蓋函式printArea
。