lua实现面向对象深度解析

先了解一下原表 __index __newindex
__index
步骤1.在表中查找,如果找到,返回该元素,找不到则继续步骤2
步骤2.判断该表是否有元表,如果没有元表,返回nil,有元表则继续步骤3
步骤3.判断元表有没有__index方法,如果__index方法为nil,则返回nil;如果__index方法是一个表,则重复步骤1、2、3;如果__index方法是一个函数,则调用该函数,并返回该函数的返回值

__newindex 可以等于一个表 也可以等于一个函数
__newindex只会在添加原表没有的键值时才会调用

lua和C#几个不同的点

仔细思考C#面向对象的主要逻辑:封装 继承 多态
1.封装 多态: 一个class可以被new出来 new出来的对象只是拥有class的一些数据或函数的定义
在lua中local一下就好了
2.继承:可以被继承 重写 访问父类对象 在lua中 setmetatable(table, __index)就能实现
但需要注意的是lua中 在lua中如果函数调用在函数声明的前面 是访问不到的 可以通过__index来实现

下面这个类算是公司一直在用的 以及上线了的基类
不想暴露公司的源代码 类名以及一些其它的东西改了一下
如果需要用的话 建议仔细了解每行代码为什么这样些的原因 如果有不了解的 欢迎提问

local _class = {}

function NewClass(className, base)
    -- 在创建对象的时候自动调用 在lua中local相当于C#的new
	local oneClass = {
        init = nil,
        delete = nil,
        name = className,
        base = base,
    }

    oneClass.New = function(...)
        -- 生成一个类对象 给外部提供的一个New方法 用来执行初始化函数 以及注册delete
        local obj = {
            _oneClass = oneClass
        }    

        -- 在初始化之前注册基类方法
        setmetatable(obj, { 
			__index = _class[oneClass],
		})
	    -- 调用初始化方法
        do
            local function create(c)
                if c.base then
                    create(c.base)
                end

                if c.init then
                    c.init(obj)
                end
            end

            create(oneClass)
        end
        -- 注册一个delete方法
        obj.delete = function(self)
            local now_base = self._oneClass
            while now_base ~= nil do
                if now_base.delete then
                    now.delete(self)
                end
                now_base = now_base.base
            end
        end

        return obj
    end

   --数据的内存地址不能一样  相当于new出来一个新的class类
	local vtbl = {}
	_class[oneClass] = vtbl
 
	setmetatable(oneClass, {
		__newindex = function(t,k,v)
			vtbl[k] = v
		end
		, 
		--在lua中如果函数调用在函数声明的前面 是访问不到的 想要实现就通过__index 访问父类对象95行__index
		__index = vtbl,
	})
 
	--有父类才需要访问父类 访问父类的父类的对象这样就能实现 因为如果有父类的父类 父类也是需要继承BaseClass
	if base then
		setmetatable(vtbl, {
			__index = function(t,k)
				--返回从_class缓存的数据
				local ret = _class[base][k]
				return ret
			end
		})
	end

    return oneClass
end

测试类

local a = NewClass("aaaaaaa")
function a:init()
	self.aaaaa = "aaaaa"
end

local b = NewClass("bbbbb", a)
function b:init()
	self.bbbbb = "bbbbb"
end

local c = NewClass("ccccc", b)
function c:init()
	self.ccccc = "ccccc"
end

local c1 = c.New()
print("+++++++++c1", c1.ccccc)
print("+++++++++b", c1.bbbbb)
print("+++++++++a", c1.aaaaa)

参考
云风的博客 实现面向对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值