初始化属性
本课属于 Coddy Lua 学习旅程的“面向对象编程”单元。第 9 课,共 70 课。
你学过的 :new() 构造函数会创建对象,但每个实例一开始都完全相同。实际使用的对象需要有独特的数据:一个人有具体的姓名,一个玩家有初始分数。要让对象发挥作用,构造函数必须接收参数,并将它们赋给新实例。
下面介绍如何扩展构造函数,使其接受初始值:
local Dog = {}
Dog.__index = Dog
function Dog:new(name, breed)
local instance = {}
setmetatable(instance, self)
instance.name = name
instance.breed = breed
return instance
end
function Dog:introduce()
print("I am " .. self.name .. ", a " .. self.breed)
end构造函数现在将 name 和 breed 作为参数。创建空实例并设置其元表后,我们会将这些值直接赋给实例的字段。创建的每个对象都有自己的 name 和 breed。
local dog1 = Dog:new("Rex", "German Shepherd")
local dog2 = Dog:new("Bella", "Poodle")
dog1:introduce() -- 输出:我是 Rex,一只德国牧羊犬
dog2:introduce() -- 输出:我是 Bella,一只贵宾犬两只狗共享原型中的同一个 :introduce() 方法,但每只狗的实例表中都存储着自己独有的名字和品种。这就是将原型与带参数的构造函数结合起来的优势:共享行为,同时保留各自的状态。
挑战
简单我们来创建一个 Person 类,让每个对象都有自己的姓名和年龄。你会把代码分成两个文件,以练习正确的模块结构。
你将创建:
Person.lua:定义Person类,并创建一个接受姓名和年龄的构造函数。添加一个:introduce()方法,让每个人都能自我介绍。main.lua:引入 Person 模块,并使用提供的输入创建一个 Person 实例。然后让这个实例进行自我介绍。
:new(name, age) 构造函数应接受这两个值,并将它们存储在新实例中。:introduce() 方法应按照以下格式准确输出:
Hello, my name is [name] and I am [age] years old你将收到两个输入:
- 这个人的姓名
- 这个人的年龄
例如,如果输入是 Alice 和 25,输出应为:
Hello, my name is Alice and I am 25 years old亲手试试
-- 加载 Person 模块
local Person = require('Person')
-- 读取输入
local name = io.read()
local age = io.read()
-- TODO:使用 Person:new(name, age) 创建一个新的 Person 实例
-- TODO:在你的 Person 实例上调用 introduce() 方法
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Lua 在线编译器