为什么 .__index 只返回子类的函数,而不是基类的函数

item = {y = 21}

function item:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end

function item:Run()
    print("item running")
end

berry = item:new{x = 52}

function berry:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end
function berry:Run()
    print("berry is running")
    self.__index:Run()
end

berry:new{b = 32}:Run()

输出无限制地打印“berry is running”,而不是应该先打印“berry is running”,再打印“item running”。如果我将self.__index更改为self.__index.__index甚至是self.__index.__index.__index,输出仍旧无限制地打印“berry is running”。我该怎么解决这个问题?任何帮助都将不胜感激

点赞
用户7396148
用户7396148

你在你的 berry 中重写了你的 itemRun 函数,这使得它更难以访问。这个覆盖导致了你的无限循环,因为 self.__index 是一个对 self 的引用,self 是一个 berry。现在 Runberry 中被定义,当用 Run 索引 berry 时,__index 将不再被调用。

因此,你的 berry:Run 函数本质上是这样的:

function berry:Run()
    print("berry is running")
    berry:Run()
end

我建议你改变你的 berry:Run 函数,并在其中特别调用 item.Run

function berry:Run()
    print("berry is running")
    item.Run(self) -- 特别调用 item.Run 并将 self 传递进去。
end

这将给你所期望的输出:

berry is running

item running


或者你可以通过在 berry 中定义 item:Run 函数来保留 item:Run 函数:

berry.ParentRun. = berry.Run -- 这将导致 __index 运行并获取 item:Run
function berry:Run()         -- 这现在定义了 berry.Run,现在 __index 不会再为 berry.Run 运行
    print("berry is running")
    self:ParentRun()
end

附加说明:

你在评论中看到的

berry is running

berry is running

item running

是因为运行的顺序是

object:Run() -- 这调用 berry 并传递了 object 的 self

打印我们的第一个 berry is running

现在我们获取了那个对象的元表,它是 berry,并调用了它的 run

berry:Run()

打印我们的第二个 berry is running

最后,我们获取了 item 的元表(它是 berry 的元表),并调用了它的 run

item:Run()

打印 item running

2020-01-02 20:08:00