也谈Lua的面相对象机制

      最近闲来无事想要学习一下cocos2dx,在知乎上看到一个讨论cocos2dx + lua合适还是cocos2dx + js合适的问题,链接http://www.zhihu.com/question/21130385,看到排名第3的回答中居然把Lua的缺点列出了不支持面向对象。。。。想来我们的项目虽然没有采用cocos2dx,但是也是采用的自研引擎+Lua的模式,Lua的面相对象,几乎是比比皆是,真的是不做调研就没有发言权,希望同做开发的同仁们在对一些事物发表意见的时候多做调查,宁可不做判断也不要做出“想当然”的判定,要不Lua真的死的冤枉阿!

  Lua的面相对象机制是基于metatable的,要实现类似java等面向对象语言的“类”的形式,我们定义了全局函数

function class(super, autoConstructSuper)
    local classType = {};
    classType.autoConstructSuper = autoConstructSuper or (autoConstructSuper == nil);
    
    if super then
        classType.super = super;
        local mt = getmetatable(super);
        setmetatable(classType, { __index = super; __newindex = mt and mt.__newindex;});
    else
        classType.setDelegate = function(self,delegate)
            self.m_delegate = delegate;
        end
    end

    return classType;
end

  

 用这个class实现"类",并定义父类实现继承

function super(obj, ...)
    do 
        local create;
        create =
            function(c, ...)
                if c.super and c.autoConstructSuper then
                    create(c.super, ...);
                end
                if rawget(c,"ctor") then
                    obj.currentSuper = c.super;
                    c.ctor(obj, ...);
                end
            end

        create(obj.currentSuper, ...);
    end
end

 

当然也要实现类的构造和析构函数

function new(classType, ...)
    local obj = {};
    local mt = getmetatable(classType);
    setmetatable(obj, { __index = classType; __newindex = mt and mt.__newindex;});
    do
        local create;
        create =
            function(c, ...)
                if c.super and c.autoConstructSuper then
                    create(c.super, ...);
                end
                if rawget(c,"ctor") then
                    obj.currentSuper = c.super;
                    c.ctor(obj, ...);
                end
            end

        create(classType, ...);
    end
    obj.currentSuper = nil;
    return obj;
end


function delete(obj)
    do
        local destory =
            function(c)
                while c do
                    if rawget(c,"dtor") then
                        c.dtor(obj);
                    end
              
                    c = getmetatable(c);
                    c = c and c.__index;                   
                end
            end
        destory(obj);
    end
end

这样,我们就可以轻松的通过lua实现面向对象机制,在实现子类的时候,lua编译器会通过metatable遍历其super父类找到它的构造方法,对于构造和析构都会循环这一过程直到找到它的基类,然后顺序执行构造(析构),而类的其他接口也可以实现继承,子类中定义父类的方法会覆盖,如果想要同时调用父类接口并实现子类的特定方法,只需要在接口中加入super.func(self)即可

posted @ 2014-04-23 11:46  wanghuanhust  阅读(297)  评论(0编辑  收藏  举报