lua可以通过元表和元方法完成面向对象编程设计,思想和javascript差不多,都是self语言
第一种是采用闭包的方式,将对象属性和方法封装在闭包里,创建对象时只需复制属性和方法就行了,缺点也显而易见,这是一种伪共享机制,创建对象时要复制类中所有属性和方法,而不是引用,这就造成用这种方法创建过多对象会浪费内存
local function newStudent()
local student = {}
student.name = ""
student.age = ""
student.sex = ""
student.setName = function(name)
student.name = name
end
student.setAge = function(age)
student.age = age
end
student.setSex = function(sex)
student.sex = sex
end
local meta = {
__index = function(_,k)
local s = string.format("undefind reference to %s",k)
error(s)
end,
__newindex = function(_,k)
local s = string.format("can't assign `%s` property for object",k)
error(s)
end
}
setmetatable(student,meta)
return student
end
local s1 = newStudent()
s1.setName("Marco")
local s2 = newStudent()
s2.setName("Epsilion")
print(s1.name)
print(s2.name)
--print(s1.lalal) --occur error
--s1.hello = "www"
第二种则比较牛逼一点,采用了类似写时复制技术,创建对象时共享类(其实也是一个表)的数据,等到通过对象再次访问时就会在对象instance表中创建属性
local Student = {name = "",sex = "",age = ""}
function Student:new(t)
t = t or {}
self.__index = self;
local meta = {
__index = function(_,k)
local s = string.format("can't read non-exist property `%s` for class Student instance",k)
error(s)
end
}
self.__newindex = function(t,k,v)
if k == "name" or k == "sex" or k == "age" then
rawset(t,k,v)
return
end
local s = string.format("can't set property `%s` of class Student instance",k)
error(s)
end--
setmetatable(self,meta)
setmetatable(t,self)
return t
end
function Student:setName(name)
self.name = name
end
function Student.setSex(sex)
self.sex = sex
end
function Student.setAge(age)
self.age = age
end
local s1 = Student:new()
s1:setName("Marco")
print(s1.name)
local s2 = Student:new()
print(s2.name)
--print(s1.hello) -- error occur
--s1.nana = "hello"; -- error occur
版权声明:本文为RGBMarco原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。