【问题标题】:Is inheritance in Lua prototype-based or class-based?Lua 中的继承是基于原型的还是基于类的?
【发布时间】:2016-08-27 12:44:16
【问题描述】:

Lua 通常被描述为具有基于原型的继承(例如在this answer 中)。然而,“Lua 编程”的"Inheritance" section 谈到了“基类”和“超类”——来自基于类的继承的术语。

哪种模型(基于原型或基于类)最能描述 Lua 中的继承方式?

【问题讨论】:

  • Lua 没有“继承”或“类”。但是可以在 Lua 中模拟它。通过一些额外的工作,您可以将 Lua 表视为类。
  • 不用担心贴什么标签。只需了解元表如何工作的实际机制即可。贴一个标签或另一个标签对你没有帮助。

标签: class inheritance lua prototype


【解决方案1】:

Lua 是基于原型的。

从技术上讲,Lua 中没有继承基类超类。 Lua 有一些像元表这样的工具来模拟经典的 OOP。 PiL 书使用这些术语的主要原因是为了让读者更容易理解。

如果您喜欢语言律师描述语法的方式,请阅读the reference manual,您不会在其中找到这些术语。

【讨论】:

    【解决方案2】:

    Lua 有一个prototype-based inheritance system。让我们首先确保我们了解 Lua 没有类,并且实际上每个对象都属于同一类型 (table)。为了模仿类的概念,lua 使用元表在表上定义一组属性,这些属性在表本身上没有定义。两个表可以共享相同的行为,因为我们可以用元表“原型化”一个对象。

    table1 = {}
    table2 = {}
    
    behavior = {myfunction = function() return 10 end}
    
    setmetatable(table1, behavior)
    setmetatable(table2, behavior)
    
    table1.myfunction()   --> 10
    table2.myfunction()   --> 10
    

    这样,table1table2 具有相同的行为并且可以被认为具有相同的“类”,即使我们实际上只是在两个不同的表上定义了相同的行为。

    要创建继承的概念,有很多选择。就个人而言,我喜欢创建一个元表的想法,以及我想从中“派生”出来的programmatically merging the fields on the metatables。然后,使用这个新的合并元表,我们可以在我们的新对象上设置元表。

    behavior_derived = {myNewFunction = function() return 20 end}
    
    -- merge the base behavior in with our derived behavior
    for k,v in pairs(behavior) do behavior_derived[k] = v end
    
    a_derived = {}
    b_derived = {}
    
    setmetatable(a_derived, behavior_derived)
    setmetatable(b_derived, behavior_derived)
    
    a_derived.myfunction()      --> 10
    a_derived.myNewFunction()   --> 20
    
    b_derived.myfunction()      --> 10
    b_derived.myNewFunction()   --> 20
    

    这是 Lua 最接近我能想到的从其他人那里派生“类”的方法。

    【讨论】:

      猜你喜欢
      • 2010-10-23
      • 1970-01-01
      • 2015-01-20
      • 2021-01-27
      • 2019-07-30
      • 2019-05-10
      • 2012-08-25
      • 1970-01-01
      相关资源
      最近更新 更多