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)
[ ]: