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

我基本上不寻求如何做某件事的答案,但我找到了如何做到这一点,还希望获得更多信息。 希望这类问题在这里是可以的。 由于我刚刚发现这个我正在修改的游戏的代码,我不知道我应该谷歌什么。

在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

.... --在某个函数中的某个地方,使用帐户实例: a1.withdraw = a1.withdrawBetter `

这种"技术"的名称是什么,以便我可以找到一些更多的信息(可能 pitfalls, 性能考虑与override将覆盖等)? 请注意,我仅更改withdraw用于特定实例(a1),而不是每个帐户实例。

附加问题:是否有其他面向对象的编程语言具有此类功能?

谢谢

点赞
用户4984564
用户4984564

Lua 中的面向对象技术

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

如果您想在 Lua 中使用面向对象编程,您需要自己实现它。通常,这是通过创建一个充当“类”的表格来完成的,该表格存储“实例方法”,这些方法实际上只是接受实例作为第一个参数的函数。

然后通过让“构造函数”(也只是一个函数)创建一个新表并将其元表设置为一个具有指向类表的 __index 字段的表来实现继承。当在使用一个实例的索引一个它没有的键时,它会在类中查找该键。

换句话说,一个“实例”表可能根本没有函数,但是如果使用例如 "withdraw" 索引它,它将尝试在类中索引它。

现在,如果我们将单个“实例”表格添加一个 withdraw 字段,Lua 将看到它具有该字段,并且不会在类中查找它。你可以说这个值是该类表格中该字段的一个_影子_。

这种“技术”的名称是什么

它实际上没有名称,但您绝对应该研究一下元表。

支持这种技术 的语言中,比如 Ruby(参见下文),通常使用单例类来实现这一点,这意味着它们只有一个实例。

性能考虑

索引表格,包括元表,需要一些时间。如果 Lua 在实例表中找到一个方法,那么这只需要进行单个的表查找;如果它没有,那么它需要先获取元表,然后再在其中查找,如果那里也没有,它还需要获取它自己的元表,以此类推。

换句话说,这实际上_更快_。它确实使用了一些额外的空间,但不是真正的很多(_从技术上讲_,可能相当多,但您真的不应该担心这个。不过,如果您想了解更多信息,可以在这里阅读)。

还有其他的面向对象编程语言使用这种“技术”吗?

是的,有很多。Ruby 就是一个很好的例子,您可以这样做:

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

def array1.foo
  puts 'bar'
end

array1.foo # 输出 'bar'
array2.foo # 引发 `NoMethodError`
2019-02-08 12:37:40