Lua 没有内置 class

但用 metatable 几行就能模拟。最常见模式:

local Animal = {}
Animal.__index = Animal

function Animal.new(name, sound)
    local self = setmetatable({}, Animal)
    self.name = name
    self.sound = sound
    return self
end

function Animal:speak()
    print(self.name .. " says " .. self.sound)
end

-- 用
local cat = Animal.new("Whiskers", "meow")
cat:speak()         -- Whiskers says meow

关键点

  1. Animal.__index = Animal:让实例查不到 key 时回退到 Animal 表上的方法
  2. function Animal:speak() = function Animal.speak(self, ...)——冒号自动加 self
  3. cat:speak() = Animal.speak(cat)——冒号调用自动传 self

继承

local Dog = setmetatable({}, {__index = Animal})  -- Dog 的 metatable.__index = Animal
Dog.__index = Dog                                  -- 实例查 Dog

function Dog.new(name)
    local self = Animal.new(name, "woof")          -- 调父构造
    return setmetatable(self, Dog)                 -- 改 metatable
end

function Dog:fetch()
    print(self.name .. " fetches the ball")
end

local rex = Dog.new("Rex")
rex:speak()     -- Rex says woof(继承)
rex:fetch()     -- Rex fetches the ball

链式查找:实例 → Dog → Animal。

覆盖与调用父方法

function Dog:speak()
    Animal.speak(self)              -- 父方法
    print("(loudly)")
end

显式调 Animal.speak(self)——没有 super 关键字。

私有字段(约定)

function Animal.new(name)
    local self = setmetatable({}, Animal)
    self._name = name       -- 下划线 = 约定私有
    return self
end

Lua 没访问控制——靠命名约定。要真私有用闭包:

function Counter()
    local n = 0
    return {
        inc = function() n = n + 1 end,
        get = function() return n end,
    }
end

local c = Counter()
c.inc(); c.inc()
print(c.get())     -- 2
-- c.n 不可访问

多重继承(不推荐,但能做)

local function search(k, plist)
    for _, parent in ipairs(plist) do
        local v = parent[k]
        if v then return v end
    end
end

local function createClass(...)
    local parents = {...}
    local c = setmetatable({}, {__index = function(t, k) return search(k, parents) end})
    c.__index = c
    return c
end

复杂场景请避免多重继承——重构成组合更清晰。

哪些库简化了 OOP

  • middleclass:经典 OOP 库
  • Penlight class:Penlight 内置
  • Roblox / Luau:自家 OOP 风格(类型注解 + Studio 工具)

但用之前——先掌握上面纯手写的 5 行模式。理解了那 5 行,所有 OOP 库都看得懂。

鸭子类型

Lua 不检查"类型",看有没有那个方法

local function quack(x) x:quack() end

local duck = { quack = function() print("Quack!") end }
local dog  = { quack = function() print("Woof... I guess.") end }

quack(duck)
quack(dog)

省心也省安全——选 Luau / Teal 类型化方言要看 第 25 篇

→ 下一篇 模块与 require