lua 中的面向对象

lua 是一种脚步语言,语言本身并不具备面向对象的特性。

但是我们依然可以利用语言的特性,模拟出面向对象的特性。

面向对象的特性通常会具备:封装,继承,多态的特性,如何在lua中实现这些特性,最主要的就是利用了lua的table和metatable。

  table是一种强大的关联数组,它可以使用数字和字符串做key,而且可以使用点操作符访问table的元素,因此非常使用用于存储一个对象的属性;

  metatable依然可以认为是一种关联数组,但是元表的作用更加强大,主要是:

    1.定义算术操作符和关系操作符的行为

    2.为 Lua 函数库提供支持

    3.控制对 table 的访问

  利用这个特性,我们可以把某个对象的方法存在元表中,当访问对象的方法时,如果自身不具备这个方法,就会在元方法中去寻找,因此利用元表可以轻松实现继承和多态的特性;

关于lua的具体实现:

-- 检查类名是否合法,要求是字符串
function validateClassName(className)
    local _type = type(className);
    
    if (_type == "string") then
        local _len = string.len(className)
        
        if (_len <= 40) then
            return true
        else
            print("[error] class name length is greater than 40")
            return false
        end
    else
        print("[error] class name of class is not a string")
        return false
    end
end

-- 检查属性表是否合法,属性只允许是基本类型(包括number,boolean,string,table,nil)
 function validatePropTabel(propTable)
    for _, _v in pairs(propTable) do
        local _propType = type(_v);
        
        if (_propType == "number" or
            _propType == "boolean" or
            _propType == "string" or
            _propType == "table" or
            _propType == "nil") then
            return true
        else
            print("[error] prop of class only support base type(number, boolean, string, table, nil), current type is ".._propType)
            return false
        end
    end
 end
 
 -- 检查父类是否合法,父类目前只支持table类型
 function validateSuperClass(superClass)
    local _superType = type(superClass)
 
    if (_superType == "table" or
        _superType == "nil") then
        return true
    else
        print("[error] super class is not a table")
        return false
    end
 end

-- className: 创建新类的类名
-- propTable: 新类的属性
-- superClass: 父类
function class(className, propTable, superClass)
    print("------------------------------------------------------")
    print("[info] create new class <"..className..">:")
    
    -- 验证参数合法性
    if (not validateClassName(className) or 
        not validatePropTabel(propTable) or 
        not validateSuperClass(superClass)) then
        return nil
    else
        print("[info] arguments validated")
    end
    
    -- 创建新类
    local subClass = {}
    -- 设置类名
    subClass.__className = className
    -- 设置元方法
    subClass.__index = subClass
    -- 设置属性表
    subClass.props = propTable
    -- 设置父类
    if (superClass) then
        setmetatable(subClass, superClass)
        subClass.super = superClass
        
        print("[info] extended from super class "..superClass.__className)
    else
        subClass.super = nil
    
        print("[info] super class is nil")
    end
    
    -- 设置默认构造函数
    if (not subClass.ctor) then
        subClass.ctor = function(...)
            print(className.." default construct...")
        end
        
        print("[info] add default constructor")
    end
    -- 设置默认的析构函数
    if (not subClass.dtor) then
        subClass.dtor = function()
            print(className.." default destruct...")
        end
        
        print("[info] add default destructor")
    end
    
    -- 设置new方法
    subClass.new = function(...)
        -- 创建一个新的实例
        local instance = {}
        
        -- 继承父类默认的属性
        local _cls = subClass.super
        while (_cls) do
            if (_cls.props) then
                print("------------------------------------------------------")
                print("[info] extended prop from super class <".._cls.__className..">:")
                for _k, _v in pairs(_cls.props) do
                    print("[info] ".._cls.__className.." key:"..tostring(_k).." value:"..tostring(_v))
                    instance[_k] = _v
                end
                print("------------------------------------------------------")
            end
            _cls = _cls.super
        end
        -- 设置本类的属性
        if (propTable) then
            print("------------------------------------------------------")
            print("[info] extended prop from super class <"..className..">:")
            for _k, _v in pairs(propTable) do
                print("[info] "..className.." key:"..tostring(_k).." value:"..tostring(_v))
                instance[_k] = _v
            end
            print("------------------------------------------------------")
        end
        
        -- 设置实例的元表为本类
        setmetatable(instance, subClass)
        -- 调用实例的构造函数
        instance:ctor(...)
        
        print("[info] create instance of class <"..className..">")
        
        return instance
    end
    -- 设置delete方法
    subClass.delete = function(instance)
        -- 调用实例的析构函数
        instance:dtor()
    
        -- 删除实例的数据
        print("------------------------------------------------------")
        print("[info] delete prop from super class <"..className..">:")
        for _k, _v in pairs(instance) do
            print("[info] "..className.." key:"..tostring(_k).." value:"..tostring(_v))
            instance[_k] = nil
        end
        print("------------------------------------------------------")
        -- 删除实例的元表
        setmetatable(instance, nil)
        -- 删除实例
        instance = nil
        
        print("[info] delete instance of class <"..className..">")
    end
    
    print("------------------------------------------------------")
    
    return subClass
end