【问题标题】:Problem with inheritance with Lua (attempt to call field 'String' (a nil value))Lua 的继承问题(尝试调用字段“字符串”(零值))
【发布时间】:2021-08-16 00:54:43
【问题描述】:

我对 Lua 的继承有困难。 我收到一个错误

“错误:main.lua:32:尝试调用字段'String'(一个零值)”

我误会了什么? 我不明白我的例子与:https://www.lua.org/pil/16.2.html

Animal = {}

function Animal:New()
    a = {}
    setmetatable(a,Animal)
    a.__index = Animal

    return a
end

function Animal:String()
    print("I am an animal")
end

Cat = {}

function Cat:New()
    c = Animal:New()
    setmetatable(c,Cat) -- Set metatable to be Cat
    c.__index = Animal -- Inherits from Animal

    return c
end

-- Overwriting Bark
function Cat:String()
    print("I am a cat")
end


c = Cat:New() -- Should return a cat
print(c:String())

【问题讨论】:

    标签: inheritance lua


    【解决方案1】:

    您的代码与 PiL 中的示例之间存在一些差异。

    1. Account.new 使用self,而不是Account 作为新对象的元表。 self 可能指代Account 或任何子类。

    2. Account.newself 上设置__index,而不是新对象。这是必要的,因为元方法必须在元表上而不是对象本身上才能产生任何效果。

    3. SpecialAccount 是用Account:new() 创建的,而不是一个普通的空表。请注意,该系统使用new 方法来创建子类和实例。

    4. SpecialAccount 没有定义new 方法。它只是从Account 继承一个。

    错误是因为c的元表是Cat,但Cat没有__indexSpecialAccount__index 在创建实例时由其 new 方法设置。

    【讨论】:

    • 我不想在真正需要 Cat 对象之前调用 Animal:New(),这就是为什么 Cat 设置为 {} 但我仍然想要一个继承自 Animal 的 Cat 类。在 lua 示例中,SpecialAccount 是一个使用 Account:New() 初始化的对象,而我想要一个实例化 Cat 的 Cat 类。有没有办法做到这一点?
    • 听起来您需要一种方法来将子类化与实例化分开。就像我在回答中所说的那样,Account:new() 完成了这两项工作。有很多方法可以做你想做的事,但 PiL 中的示例不是其中之一。查看lua-users.org/wiki/ObjectOrientedProgramming
    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 2015-04-28
    • 2011-11-05
    • 1970-01-01
    • 2016-06-21
    • 2014-04-04
    • 2021-05-15
    • 1970-01-01
    相关资源
    最近更新 更多