Lua面向對象

面向對象編程(OOP),是指我們在編程的新時代中最常用的編程技術。有多種編程語言的支持OOP其包括:

  • C++

  • Java

  • Objective-C

  • Smalltalk

  • C#

  • Ruby

面向對象的特性

  • 類: 類是可擴展的模板用來創建對象,提供狀態的初始值(成員變量)和行爲的實現。

  • 對象: 它是類的實例並具有分配給自己獨立的內存。

  • 繼承: 它是由變量和類的函數被其他類繼承的概念。

  • 封裝: 它是將數據和函數相結合的一類內的方法。數據可以在類的外部與函數的幫助下進行訪問。它也被稱爲數據抽象。

Lua的OOP

在Lua中實現面向對象與表和Lua的第一類函數。通過將函數和相關數據插入表中形成一個對象。繼承可以在metatables的幫助下來實現,提供了一個查找機制不存在的函數(方法)和在父對象字段。

在Lua表有這樣的狀態和標識對象,它是獨立於值的特性。兩個對象(表),具有相同的值但在不同的對象,而一個對象可以具有在不同的值,但它始終是相同的對象。就像對象表中有一個生命週期,獨立創建或被創建。

一個真實世界的例子

面向對象的概念是廣泛的,但要明白和獲取最大利益。

讓我們考慮一個簡單的數學例子。我們經常會遇到,我們工作在不同的形狀像圓形,長方形和正方形的情況。

形狀可以有一個共同的屬性區。因此,我們可以從與共同屬性區域的基礎對象形狀擴展的其它形狀。每個形狀都可以有其自己的性質和功能類似的矩形可以有屬性的長度,寬度,面積作爲其屬性,printArea中和calculateArea作爲它的函數。

創建一個簡單的類

一個簡單的類實現矩形三個屬性面積,長度和寬度如下所示。它也有一個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: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的繼承

繼承是擴展形狀簡單的基本對象,以矩形,正方形等的處理。它通常用於在真實世界中的共享和擴展的基本性質和功能。

讓我們看一個簡單的類擴展。有一個類,如下圖所示。

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

我們可以擴展的形狀爲正方形類如下所示。

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

繼承完整的例子

Lua中我們可以擴展的簡單類實現,如上圖所示metatables另一個新的方法。所有的成員變量和基類的函數被保留在派生類。

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

在上面的例子中,我們創建了兩個派生類Rectangle和Square從基類Square。因此能夠在此改變基類的功能的派生類。在本實現例子中,派生類會取代函數printArea。