仅为 LUA 中的特定实例覆盖函数

Overwrite function only for a particular instance in LUA

我基本上不会寻找有关如何做某事的答案,但我找到了如何做,但还需要更多信息。希望这种问题在这里没问题。 因为我刚刚发现了这个我正在修改的游戏代码,所以我不知道我应该 google 做什么。

在Lua中,我可以有例如:

Account = {balance = 0}
function Account.withdraw (v)
     self.balance = self.balance - v
end

我可以(在另一个 lua 文件中)

function Account.withdrawBetter (v)
    if self.balance > v then 
      self.balance = self.balance - v
    end
end

..... --在某个函数的某处,有一个 Account 实例: a1.withdraw = a1.withdraw更好 `

这个 "technique" 的名称是什么,以便我可以找到更多关于它的信息(可能的陷阱、性能考虑与 override/overwrite 等)?请注意,我只是为特定实例 (a1) 更改 withdraw,而不是为每个帐户实例更改。

奖励问题:任何其他 oo 编程语言都具有这种功能?

谢谢

OO 在 Lua

首先需要指出的是Lua没有实现面向对象编程;它没有对象、classes、继承等概念

如果你想在 Lua 中使用 OOP,你必须自己实现它。通常这是通过创建一个充当 "class" 的 table 来完成的,存储 "instance methods",它们实际上只是接受实例作为其第一个参数的函数。

然后通过让 "constructor"(也只是一个函数)创建一个新的 table 并将其元 table 设置为具有 __index 字段的一个来实现继承指向 class table。当使用 "instance" 没有的键索引时,它将在 class 中搜索该键。

换句话说,"instance" table 可能根本没有任何功能,但是用 "withdraw" 索引它只会尝试索引 class相反。

现在,如果我们取一个 "instance" table 并向其添加一个 withdraw 字段,Lua 将看到它有那个字段,而不用费心去寻找它在 class 中。你可以说这个值 shadows class table.

这个叫什么名字"technique"

它确实没有,但你一定要看看 metatables。

支持这种事情的语言中,比如在 Ruby 中(见下文)这通常是用单例 classes 完成的,意思是他们只有一个实例。

性能考虑

索引 tables,包括 metatables 需要一些时间。如果 Lua 在实例 table 中找到一个方法,那么这是一个 table 查找;如果没有,则它需要首先获取元table并对其进行索引,如果它也没有并且有自己的元table,则链会继续这样.

所以,换句话说,这实际上更快。它确实用掉了一些 space,但实际上并没有那么多(技术上 它可能会很多,但你真的不应该担心这一点。尽管如此,here's where you can read up on that,如果你愿意的话)。

任何其他具有这种功能的 oo 编程语言?

是的,很多。 Ruby 是一个很好的例子,您可以在其中执行类似

的操作
array1 = [1, 2, 3]
array2 = [4, 5, 6]

def array1.foo
  puts 'bar'
end

array1.foo # prints 'bar'
array2.foo # raises `NoMethodError`