博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lua-面向对象中类的构造
阅读量:5344 次
发布时间:2019-06-15

本文共 4027 字,大约阅读时间需要 13 分钟。

在Lua中,我们可以通过table+function来模拟实现类。

 

而要模拟出类,元表(metatable)和__index元方法是必不可少的。

为一个表设置元表的方法:

table = {}

metatable = {}

setmetatable(table, metatable) 

或者

table = setmetatable({},{})

 

下面看一个简单的例子:

local t = {    k1 = "aaa"}local mt = {    k2 = "bbb",    __index = {        k3 = "ccc"    }}setmetatable(t, mt)print("k1:", t.k1, "k2:", t.k2, "k3:", t.k3)

输出:

k1:    aaa    k2:    nil    k3:    ccc

 

从例子可以看出,查找表元素时会从表的元表的__index键中查找。

查找一个表元素的规则如下:

1.在表中查找,如果找到,返回该元素;如果找不到,继续2
2.判断该表是否有元表,如果没有,返回nil;如果有,继续3
3.判断元表中是否有__index方法,
如果__index方法为nil,返回nil;
如果__index方法是一个表,则重复 1,2,3;
如果__index方法是一个函数,则返回该函数的返回值。 

 

除了有__index元方法外,还有__newindex,__add,__sub等很多原方法,可查看Lua文档

 

在了解了元表和元方法后,我们就可以模拟类的实现了。

local A = {    a1 = "this is a1",    a2 = 100}function A.new()    local o = {}    setmetatable(o, A)    A.__index = A    return oendfunction A:Print()    print("This is A:Print ")endlocal a = A.new()a:Print()

输出结果:

This is A:Print

 

以上就是一个类的简单实现方式,当然,我们也可以把它的实现封装到一个function中,这样会更方便我们类的创建和使用。

 

下面是cocos2d引擎中,lua类的实现,以供参考:

 

local setmetatableindex_setmetatableindex_ = function(t, index)    if type(t) == "userdata" then        local peer = tolua.getpeer(t)        if not peer then            peer = {}            tolua.setpeer(t, peer)        end        setmetatableindex_(peer, index)    else        local mt = getmetatable(t)        if not mt then mt = {} end        if not mt.__index then            mt.__index = index            setmetatable(t, mt)        elseif mt.__index ~= index then            setmetatableindex_(mt, index)        end    endendsetmetatableindex = setmetatableindex_function class(classname, ...)    local cls = {__cname = classname}    local supers = {...}    for _, super in ipairs(supers) do        local superType = type(super)        assert(superType == "nil" or superType == "table" or superType == "function",            string.format("class() - create class \"%s\" with invalid super class type \"%s\"",                classname, superType))        if superType == "function" then            assert(cls.__create == nil,                string.format("class() - create class \"%s\" with more than one creating function",                    classname));            -- if super is function, set it to __create            cls.__create = super        elseif superType == "table" then            if super[".isclass"] then                -- super is native class                assert(cls.__create == nil,                    string.format("class() - create class \"%s\" with more than one creating function or native class",                        classname));                cls.__create = function() return super:create() end            else                -- super is pure lua class                cls.__supers = cls.__supers or {}                cls.__supers[#cls.__supers + 1] = super                if not cls.super then                    -- set first super pure lua class as class.super                    cls.super = super                end            end        else            error(string.format("class() - create class \"%s\" with invalid super type",                        classname), 0)        end    end    cls.__index = cls    if not cls.__supers or #cls.__supers == 1 then        setmetatable(cls, {__index = cls.super})    else        setmetatable(cls, {__index = function(_, key)            local supers = cls.__supers            for i = 1, #supers do                local super = supers[i]                if super[key] then return super[key] end            end        end})    end    if not cls.ctor then        -- add default constructor        cls.ctor = function() end    end    cls.new = function(...)        local instance        if cls.__create then            instance = cls.__create(...)        else            instance = {}        end        setmetatableindex(instance, cls)        instance.class = cls        instance:ctor(...)        return instance    end    cls.create = function(_, ...)        return cls.new(...)    end    return clsend
View Code

 

 

转载于:https://www.cnblogs.com/zzya/p/5797206.html

你可能感兴趣的文章
Android 4.2蓝牙介绍
查看>>
MyBatis的底层实现原理
查看>>
如何实现基于ssh框架的投票系统的的质量属性
查看>>
SQL Server Profiler:使用方法和指标说明
查看>>
内存虚拟化
查看>>
数据库表 copy
查看>>
WayOs固件修改:内置简单拨号王消息控制器及支持安卓手机续费
查看>>
ES6_07_Symbol属性
查看>>
卷积神经网络
查看>>
bzoj 1596: [Usaco2008 Jan]电话网络
查看>>
iOS UIView动画效果 学习笔记
查看>>
设置代码块
查看>>
NHibernate开发入门
查看>>
POJ 3281 Dining (网络流)
查看>>
iOS内存管理编程指南
查看>>
关于使用JQ scrollTop方法进行滚动定位
查看>>
一套简约漂亮的响应式博客园主题皮肤分享给你们
查看>>
guava collection/cache初探
查看>>
MySQL用户及权限管理
查看>>
ecshop后台添加菜单项,权限问题
查看>>