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

Lua使用classic库扩展类时实例属性被覆盖的原因

问题原因与解决办法

你的代码出现实例属性互相覆盖的核心原因是:子类构造函数调用父类构造时,错误地把父类本身作为self传入,导致父类的类属性被修改,所有子类实例共享了这些父类属性。

具体问题分析

在classic库中,:new()语法会自动将调用者作为第一个参数(也就是self)传入方法。你写的NonPair.super:new(1, 2)等价于NonPair.super.new(NonPair.super, 1, 2)——这里的self是父类Combination本身,而不是你创建的NonPair实例。

这就导致:

  1. 创建NonPair实例时,父类Combination的level和score被设置为1和2;
  2. 创建OnePair实例时,父类的level和score又被覆盖为1和3;
  3. 子类实例如果没有自己的属性,会向上查找父类的属性,所以两个实例的level都会变成最后一次修改的父类值。

正确写法

子类构造函数调用父类构造时,必须将当前子类实例的self传入父类的new方法,用点调用(.)而不是冒号调用(:):

Combination = Object:extend()

function Combination:new(level, score)
    self.curentCombinationValues = 0
    self.curentCombination = {}
    self.level = level
    self.score = score 
end

NonPair = Combination:extend()

function NonPair:new()
    -- 将当前实例self传入父类构造
    NonPair.super.new(self, 1, 2)
end

OnePair = Combination:extend()

function OnePair:new()
    OnePair.super.new(self, 1, 3)
end

或者更通用的写法,用self.super来指代父类,避免硬编码类名:

function NonPair:new()
    self.super.new(self, 1, 2)
end

这样修改后,父类构造函数操作的是每个子类实例自己的self,属性会被初始化在实例独立的空间里,不同实例的属性就不会互相覆盖了。

内容的提问来源于stack exchange,提问作者Андрей Дов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:12:16