Menu
CoddyTech

实例变量

本课属于 Coddy Lua 学习旅程的“面向对象编程”单元。第 12 课,共 70 课。

欢迎来到新的一章,本章将介绍对象如何管理其内部数据。你已经学会了创建类和实例,现在该探索每个实例如何存储和管理自己的独特状态了。

实例变量是只属于单个对象的字段。当你在方法或构造函数中给 self.something 赋值时,这些数据只存在于那个特定实例中。同一类的其他对象都有各自独立的副本。

存储表格等复杂数据时,这一点尤其重要。考虑一个库存系统,其中每个角色都携带不同的物品:

local Inventory = {}
Inventory.__index = Inventory

function Inventory:new()
    local instance = {}
    setmetatable(instance, self)
    instance.items = {}  -- 每个实例都有自己的空表
    return instance
end

function Inventory:addItem(item)
    table.insert(self.items, item)
end

关键行是 instance.items = {}。在构造函数中创建一个新的空表后,每个库存对象都会拥有自己的独立列表。如果你改为在类表本身中定义 items,所有实例就会意外地共用同一个表:给一个角色添加一把剑,就会让所有角色都得到这把剑!

local bag1 = Inventory:new()
local bag2 = Inventory:new()

bag1:addItem("Sword")
bag2:addItem("Potion")

print(#bag1.items)  -- 输出:1
print(#bag2.items)  -- 输出:1

每个库存都维护自己的集合。当某个实例需要跟踪独立变化的数据时,都可以使用这种模式:列表、计数器,或该对象独有的任何可变状态。

challenge icon

挑战

简单

我们来构建一个 ShoppingCart 系统,让每个购物车都维护自己的商品列表。这将演示实例变量如何让不同对象的数据彼此隔离:向一个购物车添加商品不会影响另一个购物车!

你将把代码分成两个文件:

  • ShoppingCart.lua:定义 ShoppingCart 类,让每个实例都有自己的 products 表。需要包含:
    • :new() 构造函数,为每个购物车初始化一个空商品列表
    • :addProduct(productName) 方法,将商品添加到这个购物车的列表中
    • :listProducts() 方法,每行打印一个商品
  • main.lua:引入 ShoppingCart 模块,并创建两个独立的购物车。向每个购物车添加不同的商品,以证明它们拥有彼此独立的商品库存。

你将收到 4 个输入:

  1. 要添加到购物车 A 的第一个商品
  2. 要添加到购物车 A 的第二个商品
  3. 要添加到购物车 B 的第一个商品
  4. 要添加到购物车 B 的第二个商品

在主文件中:

  1. 创建两个购物车:cartA 和 cartB
  2. 将前两个商品添加到 cartA
  3. 将后两个商品添加到 cartB
  4. 打印 Cart A:,然后列出购物车 A 中的商品
  5. 打印 Cart B:,然后列出购物车 B 中的商品

例如,如果输入是 Apple、Bread、Milk 和 Eggs,输出应为:

Cart A:
Apple
Bread
Cart B:
Milk
Eggs

请记住:关键是在构造函数中将 products 初始化为一个新的空表。这样,每个购物车实例都会拥有自己的独立列表,而不是所有购物车共用同一个表。

亲手试试

-- 加载 ShoppingCart 模块
local ShoppingCart = require('ShoppingCart')

-- 读取输入
local product1 = io.read()
local product2 = io.read()
local product3 = io.read()
local product4 = io.read()

-- TODO: 创建两个购物车:cartA 和 cartB

-- TODO: 将 product1 和 product2 添加到 cartA

-- TODO: 将 product3 和 product4 添加到 cartB

-- TODO: 打印 "Cart A:",然后列出 cartA 中的商品

-- TODO: 打印 "Cart B:",然后列出 cartB 中的商品
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Lua 在线编译器