openresty開發系列23--lua面向對象
面向對象編程(Object Oriented Programming,OOP)是一種很是流行的計算機編程架構。
java,c++,.net等都支持面向對象
面向對象特徵
1) 封裝:指可以把一個實體的信息、功能、響應都裝入一個單獨的對象中的特性。
2) 繼承:繼承的方法容許在不改動原程序的基礎上對其進行擴充,這樣使得原功能得以保存,
而新功能也得以擴展。這有利於減小重複編碼,提升軟件的開發效率。
3) 多態:同一操做做用於不一樣的對象,能夠有不一樣的解釋,產生不一樣的執行結果。在運行時,
能夠經過指向基類的指針,來調用實現派生類中的方法。
4) 抽象:抽象(Abstraction)是簡化複雜的現實問題的途徑,它能夠爲具體問題找到最恰當的類定義,
而且能夠在最恰當的繼承級別解釋問題。
一)Lua 中面向對象
對象由屬性和方法組成,lua中的面向對象是用table來描述對象的屬性,function表示方法;
LUA中的類能夠經過table + function模擬出來。
一個簡單實例
如下簡單的類表明矩形類,包含了二個屬性:length 和 width;getArea方法用獲取面積大小
新建rect.lua腳本
local rect = {length = 0, width = 0}
-- 派生類的方法 new
function rect:new (length,width)
local o = {
--設定各個項的值
length = length or 0,
width = width or 0
}
setmetatable(o, {__index = self})
return o
end
-- 派生類的方法 getArea
function rect:getArea ()
return self.length * self.width
end
return rect
-----------------test.lua------------------------
引用模塊
local rect = require("rect")
建立對象
建立對象是爲類的實例分配內存的過程。每一個類都有屬於本身的內存並共享公共數據。
local rect1 = rect:new(10,20)
local rect2 = rect:new(5,6)
訪問屬性 ----》 rect1.length
訪問成員函數 ----》rect1:getArea()
print("長度1:",rect1.length);
print("面積1:",rect1:getArea()); --- 點號 和 冒號 調用前面課程已經介紹
print("長度2:",rect2.length);
print("面積2:",rect2:getArea());
二)Lua繼承
-------------------shape基類---------------------------
local shape = {name = ""}
-- 建立實體對象方法 new
function shape:new (name)
local o = {
name = name or "shape"
}
setmetatable(o, {__index = self})
return o
end
-- 獲取周長的方法 getPerimeter
function shape:getPerimeter ()
print("getPerimeter in shape");
return 0
end
-- 獲取面積的方法 getArea
function shape:getArea ()
print("getArea in shape");
return 0
end
function shape:getVum ()
print("getVum in shape");
return 0
end
return shape
----------------------triangle繼承類----------------------------
local shape = require("shape")
local triangle = {}
-- 派生類的方法 new
function triangle:new (name,a1,a2,a3)
local obj = shape:new(name);
--1)當方法在子類中查詢不到時,再去父類中去查找。
local super_mt = getmetatable(obj);
setmetatable(self, super_mt);
--2)把父類的元表 賦值super對象
obj.super = setmetatable({}, super_mt)
--3)屬性賦值
obj.a1 = a1 or 0;
obj.a2 = a2 or 0;
obj.a3 = a3 or 0;
setmetatable(obj, { __index = self })
return obj;
end
-- 派生類的方法 getPerimeter
function triangle:getPerimeter()
print("getPerimeter in triangle");
return (self.a1 + self.a2 + self.a3);
end
-- 派生類的方法 getHalfPerimeter
function triangle:getHalfPerimeter()
print("getHalfPerimeter in triangle");
return (self.a1 + self.a2 + self.a3) / 2
end
return triangle
------------------test-----------------------
local rect = require("rect")
--local shape = require("shape")
local triangle = require("triangle")
local rect1 = rect:new(10,20)
local rect2 = rect:new(5,6)
--local shape1 = shape:new();
local triangle1 = triangle:new("t1",1,2,3)
local triangle2 = triangle:new("t2",6,7,8)
print("長度1:",rect1.length);
print("面積1:",rect1:getArea());
print("===============");
print("長度2:",rect2.length);
print("面積2:",rect2:getArea());
print("===============");
--print("shape1 getPerimeter:",shape1:getPerimeter())
print("===============");
----覆蓋了shape的方法
print("t1 getPerimeter:",triangle1:getPerimeter())
print("t1 getHalfPerimeter:",triangle1:getHalfPerimeter())
print("t2 getPerimeter:",triangle2:getPerimeter())
print("t2 getHalfPerimeter:",triangle2:getHalfPerimeter())
---- 從shape繼承的getVum方法
print("t1 getVum:",triangle1:getVum())
print("t2 getVum:",triangle2:getVum())
print("===============");
print("t2 super getPerimeter:",triangle2.super:getPerimeter())java