Class and Instance#
Overview#
Lua 语言中的 Table 是一种非常强大的数据结构. 它可以是列表, 也可以是字典, 字典的 key 就是属性. 而 key 对应的 value 则可以是一个函数. 并且 Lua 中还有元表 (metatable) 的设定, 允许你修改一些 table 的内在行为. 基于这些特性, 已经可以完全模拟出面向对象编程了. 类, 属性, 方法, classmethod, 继承, 重载, Mixin 等都可以实现.
Define a Class, Create an Instance#
class_and_instance.lua
1-- Person 类
2local Person = {}
3Person.__index = Person
4
5function Person:new(name)
6 local instance = setmetatable({}, Person)
7 instance.name = name
8 return instance
9end
10
11function Person:greeting()
12 print("Hello, my name is " .. self.name)
13end
14
15-- Student 类,继承自 Person
16local Student = {}
17Student.__index = Student
18setmetatable(Student, {__index = Person}) -- 这一行实现了继承
19
20function Student:new(name, grade)
21 local instance = Person:new(name) -- 调用 Person 的构造函数
22 setmetatable(instance, Student) -- 将实例的元表设置为 Student
23 instance.grade = grade -- 添加 Student 特有的属性
24 return instance
25end
26
27function Student:study()
28 print(self.name .. " is studying in grade " .. self.grade)
29end
30
31-- 创建实例并使用
32local person = Person:new("Alice")
33person:greeting() -- 输出: Hello, my name is Alice
34
35local student = Student:new("Bob", 10)
36student:greeting() -- 输出: Hello, my name is Bob(继承自 Person 的方法)
37student:study() -- 输出: Bob is studying in grade 10
[1]:
import subprocess
subprocess.run(["lua", "class_and_instance.lua"])
Hello, my name is Alice
[1]:
CompletedProcess(args=['lua', 'class_and_instance.lua'], returncode=0)
Hello, my name is Bob
Bob is studying in grade 10
Subclass (Inheritance)#
subclass.lua
1--[[
2这是一个在 Lua 中实现面向对象的例子. 我们将用 Lua 实现如下功能:
3
41. 定义一个类
52. 类有属性
63. 类有方法
74. 创建一个实例
85. 调用实例的方法
9
10基本上下面这段代码类似于 Python 中的这段代码:
11
12 class Person:
13 def __init__(name: str):
14 self.name = name
15
16 def greeting(self):
17 print(f"Hello, I am {self.name}")
18
19 alice = Person(name="Alice")
20 alice.greeting()
21--]]
22
23-- 定义 Person "类"
24-- 1. 我们首先创建一个表 Person, 这个表将作为我们的"类".
25local Person = {}
26-- 2. Person.__index = Person 这行代码设置元表的 __index 字段,
27-- 这允许实例访问 Person 表中定义的方法.
28Person.__index = Person
29
30-- 构造函数
31-- 3. Person.new 函数相当于 Python 中的 __init__ 方法. 它创建一个新的表 (实例),
32-- 设置其元表为 Person, 然后初始化属性.
33-- 用 ${类名}.${方法名} 的方式定义的方法类似于 Python 中的 classmethod
34function Person.new(name)
35 -- 4. setmetatable({}, Person) 创建一个新表并将 Person 设置为其元表.
36 -- 这使得新创建的对象能够访问 Person 中定义的方法.
37 local self = setmetatable({}, Person)
38 self.name = name
39 return self
40end
41
42-- 方法
43-- 5. 我们使用 function Person:greeting() 语法来定义方法. 这等同于
44-- function Person.greeting(self),其中 self 是隐式传递的.
45function Person:greeting()
46 print("Hello, I am " .. self.name)
47end
48
49-- 创建实例
50-- 6. 创建实例时, 我们调用 Person.new("Alice"), 这相当于 Python 中的 Person(name="Alice").
51local alice = Person.new("Alice")
52
53-- 调用方法
54-- 7. 调用方法使用 alice:greeting(), 这等同于 Python 中的 alice.greeting().
55alice:greeting() -- 输出: Hello, I am Alice
56
57-- 这种实现方式提供了类似 Python 的面向对象编程体验. 你可以轻松地添加更多方法或属性.
[2]:
subprocess.run(["lua", "subclass.lua"])
Hello, I am Alice
[2]:
CompletedProcess(args=['lua', 'subclass.lua'], returncode=0)
[ ]: