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。
出现继承失效基本是以下两个原因:
- 文件加载顺序错误:定义TitleState时,BaseState还没被加载进全局环境,此时
BaseState的值是nil,相当于写了Class{__includes = nil},自然不会继承任何父类方法。这是这类问题最高发的诱因。 - 误覆盖类变量:如果写过
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
相关产品推荐
相关产品推荐

