zoukankan      html  css  js  c++  java
  • lua使用表模拟类和对象的实现过程中的一些问题

      lua中使用元表并指定元表的__index来模拟实现了类和对象,下面是一个我觉得比较好用的class方法,用来模拟实现类的继承,这个在我之前的博客中也有提及:

    function class(classname, super)
        local cls
    
        if type(super) ~= "table" then
            super = nil
        end
    
        if super then
            cls = {}
            setmetatable(cls, {__index = super})
            cls.super = super
        else
            cls = {ctor = function() end}
        end
    
        cls.__cname = classname
        cls.__index = cls
    
        function cls.new(...)
            local instance = setmetatable({}, cls)
            instance.class = cls
            instance:ctor(...)
            return instance
        end
        return cls
    end

      在这个class方法中,传入的第一个参数是类名,第二个参数是这个类要继承的类。在创建指定类名的新类中,使用__cname保存类名,并在新创建的类中实现了一个new方法,使用这个new方法可以创建一个对象,在new方法中会自动调用一个ctor方法,这个方法就是我们的默认方法。这个class方法实现了类的基本继承功能,而且还是可以根据需要自己拓展的。

      使用这个方法实现继承固然是比较方便的,但是也遇到了一些问题,准确地说不是这个class方法地问题,而是lua的问题。lua不论是模拟继承还是模拟类和对象的关系,都是使用设置元表并将元表的__index值设置为元表本身的方式实现的,这就会在使用过程中产生一个问题:多个类继承一个类或者一个类创建了多个对象(也就是多个表都有同一个元表)时,以一个类创建多个对象为例,如果在元表中声明了一些元素,在对象使用过程中对元素值进行了修改,那么你就会发现再次修改某个对象中的元素值时它实际修改的是类(元表)中的元素值,导致了所有对象的这个值一并改变了???但是我们知道实例对象之间的值应该是互不干扰的,这个问题也造成了一些诡异的bug。我在使用的过程中想办法规避这些问题,下面是我目前想到的一些办法的总结:

      1.一个类不要创建多个对象,只创建一个对象(强制单例),继承同样如此,一个类被继承了,就不要让其他类继承它;

      2.在创建对象时会调用ctor方法,那么在ctor方法中将类中声明的元素值重置(也就是在对象中将类中的元素全部复制以便,这样避免在使用中产生对象表中没有某个元素的情况,不会到类表中去寻找)

      3.在类中不声明任何元素,所有的元素都在ctor构造方法中使用self点出来的方式声明(也就是说,要用的元素在构造方法中去声明,在对象表中创建,类表中根本没有,实现对象之间的隔离)

  • 相关阅读:
    什么是原型(prototype)
    angularjs input指令
    angularjs 弹出框 $modal (转)
    windows下安装wabt
    windows下安装emscripten
    windows下安装mingw
    windows下安装git
    windows下安装cmake
    windows下安装python
    trunc与round
  • 原文地址:https://www.cnblogs.com/movin2333/p/14717035.html
Copyright © 2011-2022 走看看