• 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
  • 相关阅读:
    在类中声明常量
    PHPStudy配置虚拟主机配置域名步骤
    PHPStudy配置虚拟主机步骤
    2019年7月22日星期一,简单的总结一下
    简单的面向对象
    session和cookie
    Jquery 事件绑定 bind 与on 的区别
    php try catch用法
    include,include_once,require,require_once的区别
    require与 include区别
  • 原文地址:https://www.cnblogs.com/iRidescent-ZONE/p/5505908.html
Copyright © 2020-2023  润新知