面向對象編程(OOP)是現代編程中使用最多的編程技術之一。 有許多支持OOP的編程語言包括 -
- C++
- Java
- Objective-C
- Smalltalk
- C#
- Ruby
面向對象的特點
- 類 - 類是用於創建對象的可擴展範本,為狀態(成員變數)和行為實現提供初始值。
- 對象 - 它是類的一個實例,並為自己分配了單獨的記憶體。
- 繼承 - 這是一個概念,通過該概念,一個類的變數和函數由另一個類繼承。
- 封裝 - 這是在類中組合數據和函數的過程。借助函數可以在類的外部訪問數據。 它也被稱為數據抽象。
Lua面向對象
可使用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
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
在上面的例子中,創建了兩個派生類 - 基類Square
和Rectangle
。並在派生類中覆蓋基類的函數。 在此示例中,派生類會覆蓋函數printArea
。