Lua面向对象的简易实现

Lua面向对象的简易实现

最近几天看到朋友写的Lua脚本,之前自己用的是cocos2d-x,突然想到原生的Lua是没有面向对象这个概念的,如果能给Lua加上面向对象的一个框架那对程序员来说肯定能方便很多。

首先要确认一下我们需要实现的效果,面向对象的三个特性,封装、继承、多态封装对于Lua而言其实就是把一些变量和函数,存在Lua的table中,这样在访问这个table的时候就可以访问到这些函数需要注意的是,lua的table是一个开放的表,没有private和protected权限,继承我们则可以通过Lua的元方法来实现,多态由于Lua弱类型的特点无法实现。

因此我们需要实现的效果是,在new一个类时,如果当前类具有这个函数,则调用,如果当前类没有,则查找其父类是否具有该函数,这样递归直到该类没有其父类为止,则返回一个nil

一个子类如果继承了一个类,则该子类拥有父类的相关方法,并且可以调用父类的方法,如果子类中有同名函数,则重写这个方法,下次调用的时候会调用子类的函数,而不是父类的同名函数。

那这里我们就可以通过元方法的__index和__newindex实现,首先__index指向当前类的父类,而父类的__index又指向父类的父类,因此就完成了继承和重载的效果,这里使用了__newindex是为了能够在开发者声明new函数时能够拷贝一个当前类的对象使用,子类可以通过super显式调用其父类

// An highlighted block

local function class(curClass,super)
	curClass = {}
	local curClassMeta = {}
	local tlClassValue = {}
	local function newClassFunc()
		local tClass = {}
		setmetatable(tClass,curClassMeta)
		return tClass
	end
	curClass.super = super
	curClassMeta.__index = function(_,key)
	local superClass = tlClassValue[key]
		if (not superClass) and super then
			superClass = super[key]
		end
		return superClass
	end
	curClassMeta.__newindex = function(table,key,value)
		if key == "new" then
			tlClassValue[key] = function(params)
			//这个地方不能直接给table赋值,需要新建一个临时的table用于存储,否则会循环调用当前table的__newindex元方法会报错。
			local t = newClassFunc()
			value(t,params)
			return t
			end
		else
			tlClassValue[key] = value
		end
	end
	setmetatable(curClass,curClassMeta)
	return curClass
end

测试代码


local a = class(...)
function a:new()
	self.a = 1
end

function a:funcA()
	print("1111")
end
local b = class(...,a)

function b:new(str)
	b.super.new(self)
	self.a = str
end

function b:funcA()
	print(self.a)
	print(self)
	print("BBBB")
end

local c = class(...,b)
-- function c:funcA()
-- 	print("CCCC")
-- end
local c1 = c.new()
c1:funcA()
local b1 = b.new("aaa")
b1:funcA()

输出为
1
表地址
BBBB
aaa
表地址
BBBB

最后需要注意的是新的子类必须要重写new否则会申请父类的表,调用时会调用父类的函数而不是当前子类的函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值