lua 面向对象

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

你可能感兴趣的:(Lua)