共享与独有
本课属于 Coddy Lua 学习旅程的“面向对象编程”单元。第 35 课,共 70 课。
使用继承时,了解每条数据存储的位置很重要。有些属性是共享的:在父类中定义,所有子类都可以访问。另一些属性是独有的:专门在子类或实例中创建。
请看这个层级结构:
local Animal = {}
Animal.__index = Animal
Animal.kingdom = "Animalia" -- 共享:定义在类上
function Animal:new(name)
local obj = {name = name} -- 独有:存储在每个实例中
setmetatable(obj, Animal)
return obj
endlocal Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
Dog.sound = "bark" -- 所有 Dog 对象共享
function Dog:new(name, breed)
local obj = Animal.new(Animal, name)
obj.breed = breed -- 每个 Dog 对象都有自己的 breed 属性
setmetatable(obj, Dog)
return obj
end创建 Dog 实例时,有些值直接存在于对象上,另一些则需要通过查找链获取:
local rex = Dog:new("Rex", "German Shepherd")
-- 这个实例独有(存储在 rex 上)
print(rex.name) -- "Rex"
print(rex.breed) -- "German Shepherd"-- 共享的属性(通过查找找到)
print(rex.sound) -- "bark"(来自 Dog)
print(rex.kingdom) -- "Animalia"(来自 Animal)关键区别是:在构造函数中赋给 obj 的字段是每个实例独有的,而直接定义在类表上的字段则由该类及其子类的所有实例共享。
挑战
简单让我们通过构建一个 Creature 和 Dragon 类系统,探索数据如何在继承层级中流动。你将亲眼看到哪些属性由所有实例共享,哪些属性只属于每个对象。
你要把代码分成三个文件:
Creature.lua:定义父类,并添加一个由所有生物共享的类级属性world = "Fantasy Realm"。再添加一个:new(name)构造函数,用于将生物的名称保存为实例属性。Dragon.lua:定义一个继承自 Creature 的子类。添加一个由所有龙共享的类级属性element = "fire"。你的:new(name, color)构造函数应先调用父类构造函数来处理名称,然后将color添加为每条龙各自独有的实例属性。main.lua:创建两条不同的龙,并查看它们的属性,以展示共享数据和独有数据之间的区别。
你将收到两项输入:
- 第一条龙的名称和颜色,两者用逗号分隔(例如,
Smaug,red) - 第二条龙的名称和颜色,两者用逗号分隔(例如,
Draco,gold)
在主文件中,使用各自的名称和颜色创建两条龙。然后严格按照以下顺序打印信息:
- 第一条龙的
name - 第一条龙的
color - 第二条龙的
name - 第二条龙的
color - 第一条龙的
element(从 Dragon 类共享) - 第二条龙的
element(从 Dragon 类共享) - 第一条龙的
world(从 Creature 类共享)
例如,如果输入是 Smaug,red 和 Draco,gold,输出应为:
Smaug
red
Draco
gold
fire
fire
Fantasy Realm注意,name 和 color 对每条龙都不同(独有的实例属性),而 element 和 world 对两条龙都相同(通过查找链找到的共享类属性)。
亲手试试
-- main.lua:创建龙并演示共享属性和独有属性
local Dragon = require('Dragon')
-- 读取第一条龙的输入(name,color)
local input1 = io.read()
-- 读取第二条龙的输入(name,color)
local input2 = io.read()
-- TODO:解析第一个输入,提取名字和颜色
-- 提示:使用 string.match,模式为 "([^,]+),([^,]+)"
-- TODO:解析第二个输入,提取名字和颜色
-- TODO:用名字和颜色创建第一条龙
-- TODO:用名字和颜色创建第二条龙
-- TODO:按顺序输出以下内容:
-- 1. 第一条龙的名字
-- 2. 第一条龙的颜色
-- 3. 第二条龙的名字
-- 4. 第二条龙的颜色
-- 5. 第一条龙的元素属性(由 Dragon 类共享)
-- 6. 第二条龙的元素属性(由 Dragon 类共享)
-- 7. 第一条龙的世界属性(由 Creature 类共享)
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Lua 在线编译器