Lua 面向對象
面向對象編程(Object Oriented Programming,OOP)是一種非常流行的電腦編程架構。
以下幾種編程語言都支持面向對象編程:
- C++
- Java
- Objective-C
- Smalltalk
- C#
- Ruby
面向對象特徵
- 1) 封裝:指能夠把一個實體的資訊、功能、回應都裝入一個單獨的對象中的特性。
- 2) 繼承:繼承的方法允許在不改動原程式的基礎上對其進行擴充,這樣使得原功能得以保存,而新功能也得以擴展。這有利於減少重複編碼,提高軟體的開發效率。
- 3) 多態:同一操作作用於不同的對象,可以有不同的解釋,產生不同的執行結果。在運行時,可以通過指向基類的指針,來調用實現派生類中的方法。
- 4)抽象:抽象(Abstraction)是簡化複雜的現實問題的途徑,它可以為具體問題找到最恰當的類定義,並且可以在最恰當的繼承級別解釋問題。
Lua 中面向對象
我們知道,對象由屬性和方法組成。LUA中最基本的結構是table,所以需要用table來描述對象的屬性。
lua 中的 function 可以用來表示方法。那麼LUA中的類可以通過 table + function 模擬出來。
至於繼承,可以通過 metetable 模擬出來(不推薦用,只模擬最基本的對象大部分時間夠用了)。
Lua 中的表不僅在某種意義上是一種對象。像對象一樣,表也有狀態(成員變數);也有與對象的值獨立的本性,特別是擁有兩個不同值的對象(table)代表兩個不同的對象;一個對象在不同的時候也可以有不同的值,但他始終是一個對象;與對象類似,表的生命週期與其由什麼創建、在哪創建沒有關係。對象有他們的成員函數,表也有:
function Account.withdraw (v)
Account.balance = Account.balance - v
end
這個定義創建了一個新的函數,並且保存在Account對象的withdraw域內,下麵我們可以這樣調用:
Account.withdraw(100.00)
一個簡單實例
以下簡單的類包含了三個屬性: area, length 和 breadth,printArea方法用於列印計算結果:
實例
Rectangle = {area = 0, length = 0, breadth = 0}
-- 派生類的方法 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
-- 派生類的方法 printArea
function Rectangle:printArea ()
print("矩形面積為 ",self.area)
end
創建對象
創建對象是為類的實例分配記憶體的過程。每個類都有屬於自己的記憶體並共用公共數據。
r = Rectangle:new(nil,10,20)
訪問屬性
我們可以使用點號(.)來訪問類的屬性:
print(r.length)
訪問成員函數
我們可以使用冒號 : 來訪問類的成員函數:
r:printArea()
記憶體在對象初始化時分配。
完整實例
以下我們演示了 Lua 面向對象的完整實例:
實例
Shape = {area = 0}
-- 基礎類方法 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
-- 基礎類方法 printArea
function Shape:printArea ()
print("面積為 ",self.area)
end
-- 創建對象
myshape = Shape:new(nil,10)
myshape:printArea()
執行以上程式,輸出結果為:
面積為 100
Lua 繼承
繼承是指一個對象直接使用另一對象的屬性和方法。可用於擴展基礎類的屬性和方法。
以下演示了一個簡單的繼承實例:
Shape = {area = 0}
-- 基礎類方法 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
-- 基礎類方法 printArea
function Shape:printArea ()
print("面積為 ",self.area)
end
接下來的實例,Square 對象繼承了 Shape 類:
-- 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
完整實例
以下實例我們繼承了一個簡單的類,來擴展派生類的方法,派生類中保留了繼承類的成員變數和方法:
實例
Shape = {area = 0}
-- 基礎類方法 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
-- 基礎類方法 printArea
function Shape:printArea ()
print("面積為 ",self.area)
end
-- 創建對象
myshape = Shape:new(nil,10)
myshape:printArea()
Square = Shape:new()
-- 派生類方法 new
function Square:new (o,side)
o = o or Shape:new(o,side)
setmetatable(o, self)
self.__index = self
return o
end
-- 派生類方法 printArea
function Square:printArea ()
print("正方形面積為 ",self.area)
end
-- 創建對象
mysquare = Square:new(nil,10)
mysquare:printArea()
Rectangle = Shape:new()
-- 派生類方法 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
-- 派生類方法 printArea
function Rectangle:printArea ()
print("矩形面積為 ",self.area)
end
-- 創建對象
myrectangle = Rectangle:new(nil,10,20)
myrectangle:printArea()
執行以上代碼,輸出結果為:
面積為 100 正方形面積為 100 矩形面積為 200
函數重寫
Lua 中我們可以重寫基礎類的函數,在派生類中定義自己的實現方式:
function Square:printArea ()
print("正方形面積 ",self.area)
end