Lua实现面向对象的实验

来源:互联网 发布:狗头表情软件 编辑:程序博客网 时间:2024/05/17 06:30

这样对吗?

关于实现Lua类继承的代码, 今天深入的思考了一下,首先来看看这段有问题的代码:

local ClassA ={    msg = "111",   --value    msgtable = {"v1","v2"} --table}function ClassA:New()    local new = {}    --元表赋值    setmetatable(new, {__index = self})    return newendr

现在我们调用ClassA的方法New生成子类ClassB,并创建方法Print修改ClassB的属性并打印出来:

local ClassB = ClassA:New()function ClassB:Print(str)    --对msg进行赋值    self.msg = str    --对表msgtable进行赋值    self.msgtable[1] = str    print('子类值类型:' .. self.msg)    print('父类值类型:' .. ClassA.msg)    print('子类表类型:' .. self.msgtable[1])    print('父类表类型:' .. ClassA.msgtable[1])endClassB:Print("2222")

以下是输出结果:

子类值类型msg:2222
父类值类型msg:111
子类表类型msgtable[1]:2222
父类表类型msgtable[1]:2222

看出什么问题了吗? 在类A的New方法中, 我们分别对继承类A的对象的两个属性进行赋值,一个是值类型, 一个是table类型。值类型的子类赋值并没有影响到父类ClassA的值, 可表类型的字段msgtable的赋值却同时影响到了父子类。 也就是说,直接用元表指向类自己的方式来实现继承是有缺陷的! 这种方式在子类操作父类的继承下来的table时, 会影响到父类的值。

由于table在lua中是引用传递,clone的作用就是根据传入的对象,拷贝一份内存独立的新对象出来,以下是clone的代码实现:

function clone(object)    local lookup_table = {}    local function _copy(object)        if type(object) ~= "table" then            return object        elseif lookup_table[object] then            return lookup_table[object]        end        local new_table = {}        lookup_table[object] = new_table        for key, value in pairs(object) do            new_table[_copy(key)] = _copy(value)        end        return setmetatable(new_table, getmetatable(object))    end    return _copy(object)end

未完待续。。。

0 0