码迷,mamicode.com
首页 > 其他好文 > 详细

在 slua 中使用更新的面向对象方案

时间:2015-06-02 23:15:43      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:

  上一篇记录了我使用 Slua.Class 来实现面向对象扩展 C# 中得类,但实际使用中,更多地情况是直接在 lua 中定义基类然后扩展,于是触发了我重新思考下是否两种形式应该统一用一种,目前的方案中,有一个不好的地方是,每一个派生类的实例,其实内部会有多个实例(每一个继承的类都有个对应的实例,参考 __call 的调用),所以继承层次越深,内部的实例越多,而这些父类的实例仅仅是提供了属性和方法而已,没有其它作用,这其实造成了一种浪费,但如果改动的话,我想整个结构和基础都得该,影响了本身 slua 中代码的兼容性。

  我仔细阅读了云风给出的 lua oop 方案,方法够精简,确实也解决了我想解决的问题,所有的类对象,都只有一个实例,他们查询父类的方法和属性,都通过缓存的 table 来查询,避免了浪费。但对于我个人目前的需求来讲,还有些不足:

  1. 包装的过于严实,无法直接使用 类名.静态方法名 来使用静态方法;
  2. 无法直接使用 super 关键字来访问父类方法,这样只能强制你完全重写继承的方法;(而关于我修改的 slua 中的 通过 __base 访问父类的机制,其实有缺陷,因为 只能通过 self.__base.Method(self, ...),但是 super 应该隶属于类而不是对象,应该 NewCls.__base.Method(self, ...) 这样才对。),修改完应该每个派生类会多一个实例用来指向 super 的父类访问,而这个类是共享的,所以开销可以忽略不计;
  3. 为了整体代码风格统一(提供同 Slua.Class 继承类同样的实例化类方法),我需要也添加一个默认实例化方法: local obj = NewCls(...),等同于 local obj = NewCls.new(...)。

  修改完的代码如下(请忽略我修改了变量名):

-- The hold all class type.
local __TxClassTypeList = {}

-- The inherit class function.
local function TxClass(SuperType)
    -- Create new class type.
    local ClassType = {}
    ClassType.Ctor = false
    ClassType.SuperType = SuperType

    -- Create new class instance function.
    local function ClassTypeInstance(...)
        local Obj = {}
            do
                local Create
                Create = function (c, ...)
                    if c.SuperType then
                        Create(c.SuperType, ...)
                    end

                    if c.Ctor then
                        c.Ctor(Obj, ...)
                    end
                end
 
                Create(ClassType, ...)
            end

            setmetatable(Obj, {__index = __TxClassTypeList[ClassType]})
            return Obj
    end

    -- The new function of this class.
    ClassType.new = ClassTypeInstance

    -- The super class type of this class.
    if SuperType then
        ClassType.super = setmetatable({}, 
        {
            __index = function (t, k)
                local Func = __TxClassTypeList[SuperType][k]
                if "function" == type(Func) then
                    t[k] = Func
                    return Func
                else
                    error("Accessing super class field are not allowed!")
                end
            end
        })
    end

    -- Virtual table
    local Vtbl = {}
    __TxClassTypeList[ClassType] = Vtbl
 
    -- Set index and new index of ClassType, and provide a default create method.
    setmetatable(ClassType,
    {
        __index = function (t, k)
            return Vtbl[k]
        end,

        __newindex = function (t, k, v)
            Vtbl[k] = v
        end,

        __call = function (self, ...)
            return ClassTypeInstance(...)
        end
    })
 
    -- To copy super class things that this class not have.
    if SuperType then
        setmetatable(Vtbl,
        {
            __index = function (t, k)
                local Ret = __TxClassTypeList[SuperType][k]
                Vtbl[k] = Ret
                return Ret
            end
        })
    end
 
    return ClassType
end

  现在我可以如下使用:

-- Base class.
local BaseFoo = TxClass()

BaseFoo.Name = "I am BaseFoo!"

function BaseFoo:Ctor()
    print("BaseFoo in constructor.")
end

function BaseFoo.PrintHello()
    print("Hello BaseFoo!")
end

function BaseFoo:Foo()
    print("Name is: " .. self.Name)
end

-- Derived class.
local MyFoo = TxClass(BaseFoo)

MyFoo.Age = 18

function MyFoo:Ctor()
    print("MyFoo in constructor.")
end

function MyFoo:Foo()
    MyFoo.super.Foo(self)
    print("Age is: " .. tostring(self.Age))
end

-- Create instance.
local bf = BaseFoo.new()
bf:Foo()

local mf = MyFoo()
mf:Foo()

BaseFoo.PrintHello()
MyFoo.PrintHello()

   接下来如云风所说,我应该思考下如何实现 Destructor。

 

在 slua 中使用更新的面向对象方案

标签:

原文地址:http://www.cnblogs.com/yaukey/p/4547882.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!