openresty开发系列23--lua面向对象

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