介绍两种,一种是通过设置元表,一种通过拷贝table
Shape = {perimeter = 0 , area = 0} ---相当于类,perimeter和area相当于属性
Shape.__index = Shape ----设置元方法指向自身
function Shape:New() ---- 创建对象的方法,这里类实例化类似于新建了table,这个table的元表示shape类
local temTab = {} -----新建设一个table
setmetatable(temTab,Shape) ----设置table的元表为shape,
--[[lua中table的查找顺序是先在自己table中找,如果没有就看有没有元表,如果没有元表,则直接返回nil,如果有元表判断元表是否设置了元方法,上面的__index就是这时候使用,__index方法是一张表,则重复执行,如果__index方法是一个函数,则返回该函数的返回值]]
temTab.perimeter = 3
temTab.area = 2
return temTab
end
function Shape:GetArae()
return self.area
end
function Shape:GetPerimeter()
return self.perimeter
end
Rectangle = {}
setmetatable(Rectangle, Shape) --Rectangle 通过设置原表继承自shape类
Rectangle.__index = Rectangle
function Rectangle:New(width,height)
local t = {} --初始化对象自身
setmetatable(t, Rectangle) --将对象自身元表设定为SubClass类
t.width = width
t.height = height --新的属性初始化,如果没有将会按照声明=0
return t
end
function Rectangle:GetArae()
local rectangleArea = self.width*self.height
return rectangleArea
end
acc = Shape:New()
print("acc.GetArae() "..acc:GetArae())
print("acc.GetPerimeter "..acc:GetPerimeter())
tangle = Rectangle:New(5,5)
print(" tangle.width "..tangle.width.." tangle.height "..tangle.height)
print("tangle.GetArae() "..tangle:GetArae())
print("tangle.GetPerimeter "..tangle:GetPerimeter())
Shape = {perimeter = 2 , area = 2} ---相当于类,perimeter和area相当于属性
Shape.__index = Shape ----设置元方法指向自身
function Shape:ctor()
print("base.ctor")
end
function Shape:New() ---- 创建对象的方法
end
function Shape:GetArae()
return self.area
end
function Shape:GetPerimeter()
return self.perimeter
end
function Shape:DefineSubClass()--通过拷贝的方式实现模拟类
local newClassTable = {}
for k,v in pairs(self) do --拷贝父类shape所有的属性
newClassTable[k] = v
end
newClassTable.base = self --子类的base设为父类
newClassTable.__index = newClassTable --元方法__index更新索引指向自己
local NewFunc = function(...)
local instance = setmetatable({}, newClassTable) --模拟实例化
instance:ctor(...) --调用子类的属性
return instance
end
if self.New then
newClassTable.New = NewFunc --给new赋值方法NewFunc
end
return newClassTable
end
Rectangle = Shape:DefineSubClass() --定义子类
function Rectangle:ctor() --属性,我们可以通过rawget函数来忽略元表的__index作用,只从table中查找
print("ctor")
self.base.ctor(self)
rawset(self, "width", 5)
rawset(self, "height", 5)
end
function Rectangle:GetArae()
local rectangleArea = self.width*self.height
return rectangleArea
end
print("------------------")
tangle = Rectangle:New()
print("tangle.width "..tangle.width.." tangle.height "..tangle.height)
print("tangle.GetArae() "..tangle:GetArae())
print("tangle.GetPerimeter "..tangle:GetPerimeter())
小伙伴们觉得那种方法比较好呢,欢迎讨论