zoukankan      html  css  js  c++  java
  • lua 面向对象编程类机制实现

    lua no class

    It is a prototype based language。

    在此语言中没有class关键字来创建类。

    现代ES6, 已经添加class类。 prototype based 语言没啥优势。

    lua 如何构建class机制?

    https://github.com/fanqingsong/oopclass.lua

    提供lua的 Object Oriented Programing Class 实现: 比其他实现更加轻量 https://github.com/Yonaba/Lua-Class-System 特色功能: 1、 虚类声明 2、 单例声明 3、 类冰封, 一旦冰封后, 类的属性不能被改变。

    code -- oopclass.lua

    local _M = {}
    
    -- Instantiates a class
    local function _instantiate(class, ...)
        -- 抽象类不能实例化
        if rawget(class, "__abstract") then
            error("asbtract class cannot be instantiated.")
        end
    
        -- 单例模式,如果实例已经生成,则直接返回
        if rawget(class, "__singleton") then
            -- _G[class]值为本class的实例
            if _G[class] then
                return _G[class]
            end
        end
    
        local inst = setmetatable({__class=class}, {__index=class})
        if inst.__init__ then
            inst:__init__(...)
        end
    
        --单例模式,如果实例未生成,则将实例记录到类中
        if rawget(class, "__singleton") then
            if not _G[class] then
                _G[class] = inst
    
                -- 对类对象增加实例获取接口
                class.getInstance = function ( self )
                    return _G[class]
                end
    
                -- 销毁单例,为后续建立新单例准备
                class.destroyInstance = function ( self )
                    _G[class] = nil
                end
            end
        end
    
        return inst
    end
    
    -- LUA类构造函数
    function _M.class(base)
        local metatable = {
            __call = _instantiate,
        }
    
        -- 先查原型表,然后查父亲类
        metatable.__index=function(t, k)
            local v = t.__prototype[k]
            if v then
                return v
            end
    
            local parent = t.__parent
            if parent then
                return parent[k]
            end
    
            return nil
        end
    
        -- 缓存类的field
        metatable.__newindex=function (t,k,v)
            rawset(t.__prototype, k, v)
        end
    
        local _class = {}
        -- __parent 属性缓存父类
        _class.__parent = base or {}
        -- 存储此类的所有field
        _class.__prototype = {}
    
        -- 在class对象中记录 metatable ,以便重载 metatable.__index
        _class.__metatable = metatable
    
        -- 将类冷冻,不允许新建删除修改
        _class.freeze = function ( self )
            local mt = getmetatable(self)
    
            mt.__newindex=function (t,k,v)
                error("class is frozen, cannot revise")
            end
        end
    
        return setmetatable(_class, metatable)
    end
    
    --- Test whether the given object is an instance of the given class.
    -- @param object Object instance
    -- @param class Class object to test against
    -- @return Boolean indicating whether the object is an instance
    -- @see class
    -- @see clone
    function _M.instanceof(object, class)
        local objClass = object.__class
        if not objClass then
            return false
        end
    
        while objClass do
            if objClass == class then
                return true
            end
            objClass = objClass.__parent
        end
    
        return false
    end
    
    return _M


    使用

    local oopclass = require("oopclass")
    
    local class = oopclass.class
    local instanceof = oopclass.instanceof
    
    
    local superTab =  class()
    superTab.test = function ( self )
        print("superTab test")
    end
    
    superTab:freeze()
    
    superTab.test2 = function ( self )
        print("superTab test2")
    end
    
    local tab = class(superTab)
    
    local tabObj = tab()
    tabObj:test()
    
    
    print( instanceof(tabObj, tab) )
    
    print( instanceof(tabObj, superTab) )
  • 相关阅读:
    3.java开发环境配置
    2.java主要特性
    1.java中main函数理解
    测试项目团队角色岗位职责
    单身程序员
    软件测评师考试
    vue父子组件通信
    python偏函数使用
    Numpy+Pandas读取数据
    chrome无界面模式headless配置
  • 原文地址:https://www.cnblogs.com/lightsong/p/6032028.html
Copyright © 2011-2022 走看看