Lua 本身無內建類機制,但通過 table 和 metatable 可完美模擬面向對象:
require 載入module() 創建__index 元方法指向類實現繼承__index 指向父類-- Student.lua
module("Student", package.seeall)
-- 公有靜態成員
flag = 1
-- 私有靜態成員(外部不可訪問)
local flag2 = 2
-- 非靜態方法(需傳 self)
function init(self, name)
self.name = name -- 非靜態成員變量
end
-- 靜態方法(不傳 self)
function getFlag()
return flag
end
-- 非靜態方法
function getName(self)
return self.name
end
-- tools.lua
-- 創建對象:空 table 設置 metatable 指向類
function new(moduleName)
local obj = {}
setmetatable(obj, {__index = moduleName})
return obj
end
-- 繼承:子類 metatable 指向父類
function extend(child, parent)
setmetatable(child, {__index = parent})
end
-- 創建並初始化對象
function create(moduleName, ...)
local obj = new(moduleName)
obj:init(...)
return obj
end
require "tools"
require "Student"
-- 訪問靜態成員
print("flag =", Student.flag)
print("getFlag() =", Student.getFlag())
-- 創建對象
local obj = create(Student, "xiaoming")
-- 對象訪問靜態成員(通過 __index 找到類)
print("obj.flag =", obj.flag)
-- 訪問非靜態成員
print("obj.name =", obj.name)
-- 調用非靜態方法(冒號語法糖自動傳 self)
print("obj:getName() =", obj:getName())
flag = 1 getFlag() = 1 obj.flag = 1 obj.name = xiaoming obj:getName() = xiaoming
| 概念 | 本質 | 訪問方式 |
|---|---|---|
| 公有靜態成員 | 模塊 table 中的字段 | Module.name |
| 私有靜態成員 | 模塊中的 local 變量 | 僅模塊內部可訪問 |
| 非靜態成員變量 | 對象 table 中的字段 | obj.name |
| 靜態方法 | 不接收 self 的函數 | Module.func() |
| 非靜態方法 | 首參為 self 的函數 | obj:func() 或 obj.func(obj) |
: 只是語法糖,等價於 . 並自動傳遞 selfpackage.seeall 允許模塊訪問全局環境obj -> class -> parentClass -> ...,由 __index 鏈實現此模式輕量靈活,適合 Lua 腳本開發中的物件導向設計。