Lua优雅的实现面向对象特性

1. 优雅的实现

1.1 class定义

local _class={}

function class(super)
    local class_type={}
    class_type.ctor=false
    class_type.super=super
    class_type.new=function(...) 
            local obj={}
            do
                local create
                create = function(c,...)
                    if c.super then
                        create(c.super,...)
                    end
                    if c.ctor then
                        c.ctor(obj,...)
                    end
                end

                create(class_type,...)
            end
            setmetatable(obj,{ __index=_class[class_type] })
            return obj
        end
    local vtbl={}
    _class[class_type]=vtbl

    setmetatable(class_type,{__newindex=
        function(t,k,v)
            vtbl[k]=v
        end
    })

    if super then
        setmetatable(vtbl,{__index=
            function(t,k)
                local ret=_class[super][k]
                vtbl[k]=ret
                return ret
            end
        })
    end

    return class_type
end

1.2 使用示例

1.2.1 定义基类

base_type=class()       -- 定义一个基类 base_type

function base_type:ctor(x)  -- 定义 base_type 的构造函数
    print("base_type ctor")
    self.x=x
end

function base_type:print_x()    -- 定义一个成员函数 base_type:print_x
    print(self.x)
end

function base_type:hello()  -- 定义另一个成员函数 base_type:hello
    print("hello base_type")
end

1.2.2 定义派生类

test=class(base_type)   -- 定义一个类 test 继承于 base_type

function test:ctor()    -- 定义 test 的构造函数
    print("test ctor")
end

function test:hello()   -- 重载 base_type:hello 为 test:hello
    print("hello test")
end

1.2.3 实例化派生类成员

a=test.new(1)   -- 输出两行,base_type ctor 和 test ctor 。这个对象被正确的构造了。
a:print_x() -- 输出 1 ,这个是基类 base_type 中的成员函数。
a:hello()   -- 输出 hello test ,这个函数被重载了。

2. 简介

Lua中类、对象都通过table实现。为了概念上的清晰,这里将其分开,视为不同的东西:class用于定义类结构,new用于创建对象。

2.1 class(类)

用Table作为类结构,也就是生成对象的模板。

直接定义在类上的成员(函数、变量),都是在所有对象间共享的(此处和Python一样)
类结构中,用base变量引用一个基类结构,实现了单继承。
通过__index元方法,实现了高效的基类成员检索(继承)

2.2 new(对象)

直接用元表完成对象结构的创建
_Create实现了C#的对象构造顺序(基类->子类)
在构造函数Ctor中对self赋值的变量,才是成员变量(Python方式)。当然由于动态语言的特性,在任意位置给self赋值都有效。

参考:

  1. 云风:Lua中实现面向对象
  2. 简书:Lua实现面向对象机制

全文完

你可能感兴趣的:(lua,Lua,面向对象)