You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lua使用hump.class类继承失效 父类enter方法调用报nil错误

问题现象

项目运行时抛出如下错误:
Error: src/StateMachine.lua:18: attempt to call method 'enter' (a nil value)
手动在TitleState里补空的enter方法只能临时绕过报错,核心原因是子类没有正确继承BaseState的父类方法。

环境与相关代码

项目使用hump库的class.lua实现面向对象能力。

  • 基类BaseState代码:
BaseState = Class{}

function BaseState:init() end
function BaseState:enter() end
function BaseState:exit() end
function BaseState:update(dt) end
function BaseState:render() end
  • 子类TitleState通过__includes = BaseState的方式声明继承,代码如下:
TitleState = Class{__includes = BaseState}

local highlighted = 1

function TitleState:update()
    -- 按上下方向键切换选中项
    if love.keyboard.wasPressed('up') or love.keyboard.wasPressed('down') then
        highlighted = highlighted == 1 and 2 or 1
    end

    -- 按回车确认选中项,切换状态
    if love.keyboard.wasPressed('enter') or love.keyboard.wasPressed('return') then
        if highlighted == 1 then
            gStateMachine:change('play')
        else
            love.event.quit()
        end
    end
end

function TitleState:render()

    local backgroundWidth = gTextures['background']:getWidth()
    local backgroundHeight = gTextures['background']:getHeight()

    love.graphics.draw(gTextures['background'], 0, 0, 0, VIRTUAL_WIDTH / (backgroundWidth - 1), VIRTUAL_HEIGHT / (backgroundHeight - 1))
    love.graphics.setFont(gFonts['large'])
    love.graphics.printf("Welcome to adventure", 0, VIRTUAL_HEIGHT / 3, VIRTUAL_WIDTH, 'center')

    -- 选项文本
    love.graphics.setFont(gFonts['medium'])

    -- 选中第一项时将文本渲染为青色
    if highlighted == 1 then
        love.graphics.setColor(103/255, 255/255, 255/255, 255/255)
    end
        love.graphics.printf("START", 0, VIRTUAL_HEIGHT / 2 + 70,
            VIRTUAL_WIDTH, 'center')

    -- 重置颜色为白色
    love.graphics.setColor(255/255, 255/255, 255/255, 255/255)

    -- 选中第二项时将文本渲染为青色
    if highlighted == 2 then
        love.graphics.setColor(103/255, 255/255, 255/255, 255/255)
    end
    love.graphics.printf("QUIT", 0, VIRTUAL_HEIGHT / 2 + 90,
        VIRTUAL_WIDTH, 'center')

    -- 重置颜色为白色
    love.graphics.setColor(255/255, 255/255, 255/255, 255/255)
end
故障原因

hump.class的继承逻辑对__includes字段的传值有明确要求:传入的必须是Class本身,不能是Class的实例,也不能是nil。
出现继承失效基本是以下两个原因:

  1. 文件加载顺序错误:定义TitleState时,BaseState还没被加载进全局环境,此时BaseState的值是nil,相当于写了Class{__includes = nil},自然不会继承任何父类方法。这是这类问题最高发的诱因。
  2. 误覆盖类变量:如果写过BaseState = BaseState()之类的代码把类本身覆盖成了实例,也会导致继承逻辑完全失效。
排查修复步骤
  • 第一步:检查入口文件的依赖加载顺序,必须先加载类工具,再加载BaseState基类定义,之后再加载所有继承自BaseState的状态类(比如TitleState、PlayState等),最后加载状态机和主业务逻辑。
    正确的加载顺序参考:
    -- 先加载工具依赖
    Class = require 'lib/hump/class'
    -- 再加载基类
    require 'src/states/BaseState'
    -- 再加载所有子类状态
    require 'src/states/TitleState'
    require 'src/states/PlayState'
    -- 最后加载状态机和其他逻辑
    require 'src/StateMachine'
    
  • 第二步:全局搜索代码里对BaseState的赋值操作,确保没有把类本身覆盖成实例、nil或者其他类型值的写法。
  • 第三步:验证修复效果,在TitleState定义完成后加一行调试代码:
    print(TitleState.enter)
    
    如果控制台输出是function: 0xXXXXXX格式的函数地址,就说明继承成功,不会再报方法不存在的错误。

注意:不要靠给每个子类手动补空的enter/exit/init方法绕问题,只要加载顺序正确,所有父类的空方法会自动被子类继承,不需要重复编写。

内容的提问来源于stack exchange,提问作者Takerofsoles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 13:42:04