Menu
CoddyTech

添加对象

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

你已经了解了 __tostring 和 __eq 这样的元方法如何让你自定义对象的行为。现在,我们将把它扩展到算术运算,从加法开始。

当你在两个对象之间使用 + 运算符时,__add 元方法会定义发生什么。Lua 遇到 a + b 时,会在任一操作数的元表中查找 __add。

local Vector = {}
Vector.__index = Vector

function Vector:new(x, y)
    local obj = {x = x, y = y}
    setmetatable(obj, Vector)
    return obj
end

function Vector.__add(v1, v2)
    return Vector:new(v1.x + v2.x, v1.y + v2.y)
end

注意,__add 是用点号定义的。Lua 会把两个操作数都作为普通参数传入,而点号形式会为它们分别命名。用冒号也可以,因为 function Vector:__add(other) 与 function Vector.__add(self, other) 相同,不过点号形式是惯例。__add 应该返回一个新对象,而不是修改任一原对象。这样可以让操作更可预测、更安全。

local a = Vector:new(3, 4)
local b = Vector:new(1, 2)
local c = a + b

print(c.x, c.y)  -- 输出:4  6

关键在于,__add 必须放在元表本身(这里是 Vector)中,而不能只放在对象中。由于我们将 Vector 设置为所有实例的元表,因此它们会自动共享这种行为。

challenge icon

挑战

简单

我们来编写一个支持使用 + 运算符进行加法的 Vector 类。这是你学习运算符重载的第一步,它能让你的对象自然地使用 Lua 内置运算符。

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

  • Vector.lua:定义包含 x 和 y 分量的 Vector 类。添加 :new(x, y) 构造函数,并实现 __add 元方法,让两个向量相加时生成一个分量合并后的新向量。定义 __add 时要使用点号,这样两个操作数都会作为具名参数传入。
  • main.lua:引入 Vector 模块,创建向量实例,并演示相加后能得到正确结果。

你会收到 4 个输入:

  1. 第一个向量的 x 分量
  2. 第一个向量的 y 分量
  3. 第二个向量的 x 分量
  4. 第二个向量的 y 分量

在主文件中,使用给定的分量创建两个向量,用 + 运算符将它们相加,并将结果向量的 x 和 y 值分别打印在单独的行上。

例如,如果输入是 3、4、1、2,输出应为:

4
6

第一个向量(3,4)加上第二个向量(1,2),等于一个新向量(4,6)。

亲手试试

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

-- 读取输入
local x1 = tonumber(io.read())
local y1 = tonumber(io.read())
local x2 = tonumber(io.read())
local y2 = tonumber(io.read())

-- TODO:使用输入值创建两个 Vector 实例

-- TODO:使用 + 运算符将两个向量相加

-- TODO:将结果向量的 x 和 y 值分别打印在两行
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: Lua 在线编译器