Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Inheritance 若子类的对象调用了_索引,则将继承的表成员存储到子类中_Inheritance_Lua_Meta Method - Fatal编程技术网

Inheritance 若子类的对象调用了_索引,则将继承的表成员存储到子类中

Inheritance 若子类的对象调用了_索引,则将继承的表成员存储到子类中,inheritance,lua,meta-method,Inheritance,Lua,Meta Method,我的目标是有一种标准的方法来创建具有全比例多重继承的类,并且能够通过new()-constructor不仅继承到其他类,还继承到自身的实例。如果我从类或其对象调用一个缺少的值,并且该值是一个函数,我希望将其存储到类中供以后使用,但不存储在对象/实例中(在类的大量实例中实现相同函数时会出现性能问题) 目前,我正在使用一个与官方教程系列()中提到的非常类似的createClass(…)-函数来创建从几乎任何数量的父类继承的类: -- look up for k in list of tables p

我的目标是有一种标准的方法来创建具有全比例多重继承的类,并且能够通过
new()
-constructor不仅继承到其他类,还继承到自身的实例。如果我从类或其对象调用一个缺少的值,并且该值是一个函数,我希望将其存储到类中供以后使用,但不存储在对象/实例中(在类的大量实例中实现相同函数时会出现性能问题)

目前,我正在使用一个与官方教程系列()中提到的非常类似的
createClass(…)
-函数来创建从几乎任何数量的父类继承的类:

-- look up for k in list of tables plist
local function search (k, plist)
    for i=1, #plist do
        local v = plist[i][k]     -- try i-th superclass
        if v then return v end
    end
end

local function createClass (...)
    local args = {...};
    local c = {};
    -- search all provided parent classes for variables/functions to inherit and include them
    -- could be done without including them (deeply nested inheritance might be an issue this way
    -- due to repeated search calls for each use of an inherited function)
    setmetatable(c, {__index = function (t, k)
        local v = search(k, args);
        t[k] = v;
        print(t, " ...looking for... ", k, v);
        return v;
    end})
    return c;
end
它将索引元方法传递给新创建的类,该类在所有父类中搜索指定的缺少键,并将其存储在调用类中以供以后使用。即使在搜索一个巨大的嵌套继承层次结构时,它也可以作为intendet使用。现在,让我们介绍一个具有基本构造函数的简单类:

local P = {};
local MyClass = P;

function P.new ()
    local self = {};
    local priv = {};
    setmetatable(self, {__index = function (t, k)
        -- shouldn't this invoke __index-metamethod of P because P does not already have k
        -- at this stage of the program?
        local v = P[k];
        print(t, " ...looking for ... ", k, v);
        if(type(v) == "function") then
            -- ??? maybe do somethine else here to enforce __index of class P
        else
            t[k] = v;
        end
        return v;
    end});

    self.testSelf = function () print("testSelf") end;
    priv.testPriv = "testPriv!";

    function self.accessPriv ()
        return priv;
    end

    return self;
end

function P.TEST ()
    print("calling TEST");
end
如果我们使用以下代码调用此继承和类实现,那么我们会看到在创建类的新实例时不会调用类的
\u index
-metamethod(比较输出的表地址),即使对象的
\u index
-metamethod从其(父)类请求缺少的值/函数,但此时该类没有这样的值/函数。显然,这个描述并没有调用类本身的
\uu index
-元方法,这让我感到困惑。我假设,如果请求类/表的缺少值,无论脚本的哪个部分,都会调用它

  • 为什么在给定示例中未调用
    MyClass
    \uu索引
    -元方法?
  • 我如何才能做到这一点(通过尽可能少地更改代码)?

  • 欢迎您的建议

    我没有完全理解就找到了答案。调用类的构造函数
    new
    时,需要将类本身传递给它。通过这种方式,我可以直接操作表示类的self变量。关于为什么我能够从类及其父类继承到类实例/对象,而不能访问该类以执行objetcts
    \Uuu index
    -metamethod中的任何其他操作,仍然存在困惑

    该类定义最终完成了以下工作:

    local P = {};
    local MyClass = P;
    
    -- must pass class itself while creating new object of it (don't know why...)
    function P:new ()
        local pub = {};
        local priv = {};
        setmetatable(pub, {__index = function (t, k)
            local v = P[k];
            -- store functions into the class for later use (less duplicates)
            -- and all other inherited variables into the objects itself
            if (type(v) == "function")
                self[k] = v;
            else
                t[k]    = v;
            end
            return v;
        end});
    
        pub.testSelf = function () print("testSelf") end;
        priv.testPriv = "testPriv!";
    
        function pub.accessPriv ()
            return priv;
        end
    
        return pub;
    end
    
    function P.TEST ()
        print("calling TEST");
    end
    

    另外:我假设将
    \uu index
    -元方法从对象链接到它的类,因为这就是它对类和超类的工作方式(在给定的示例中对其进行了测试)。