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)代表兩個不同的物件;一個物件在不同的時候也可以有不同的值,但他始終是一個物件;與物件類似,表的生命週期與其由什麼創建、在哪裡創建沒有關係。物件有他們的成員函數,表也有:

Account = {balance = 0}
function Account.withdraw (v)
    Account.balance = Account.balance - v
end

這個定義建立了一個新的函數,並且保存在Account物件的withdraw域內,下面我們可以這樣呼叫:

Account.withdraw(100.00)

一個簡單實例

以下簡單的類別包含了三個屬性: area, length 和breadth,printArea方法用於列印計算結果:

-- Meta class
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 物件導向的完整實例:###
-- Meta class
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 繼承

繼承是指一個物件直接使用另一個物件的屬性和方法。可用於擴充基礎類別的屬性和方法。

以下示範了一個簡單的繼承實例:

 -- Meta class
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 類別:

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

完整實例

以下實例我們繼承了一個簡單的類,來擴展派生類的方法,派生類中保留了繼承類的成員變數和方法:

 -- Meta class
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 中我們可以重寫基礎類別的函數,在衍生類別中定義自己的實作方式:

-- 派生类方法 printArea
function Square:printArea ()
  print("正方形面积 ",self.area)
end