Skip to content

面向对象编程 ​

面向对象编程(OOP)把数据和操作这些数据的函数组织成对象。Lua 没有内建的类和继承机制,但表(tables)加元表(metatables)足够实现面向对象的写法。

1. 基于表的对象系统 ​

Lua 的面向对象编程主要通过表和元表来实现。每个对象可以看作是一个表,并且可以使用元表来定义对象的行为和操作。

定义类 ​

在 Lua 中,你可以通过表来模拟类的行为。以下是一个简单的类定义示例:

lua
local Dog = {}
Dog.__index = Dog

function Dog:new(name, age)
    local instance = setmetatable({}, self)
    instance.name = name
    instance.age = age
    return instance
end

function Dog:bark()
    print(self.name .. " says: Woof!")
end

local myDog = Dog:new("Rex", 5)
myDog:bark()  -- 输出 Rex says: Woof!

在这个例子中,Dog 表模拟了一个类,Dog:new 方法用来创建新的实例,Dog:bark 方法用来定义对象的行为。

2. 继承与多态 ​

Lua 支持基于原型的继承,这意味着你可以创建一个新的表作为已有表的扩展,从而实现继承和多态。

继承 ​

lua
local Animal = {}
Animal.__index = Animal

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

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

local Cat = setmetatable({}, {__index = Animal})
Cat.__index = Cat

function Cat:new(name, breed)
    local instance = Animal:new(name)
    setmetatable(instance, self)
    instance.breed = breed
    return instance
end

function Cat:speak()
    print(self.name .. " says: Meow!")
end

local myCat = Cat:new("Whiskers", "Siamese")
myCat:speak()  -- 输出 Whiskers says: Meow!

在这个例子中,Cat 继承了 Animal 的属性和方法,并且重写了 speak 方法,从而实现了多态。

多态 ​

多态是面向对象编程的一个重要特性,允许对象以多种形式存在。通过重写父类方法,可以实现不同子类的特定行为。

lua
local function makeSound(animal)
    animal:speak()
end

makeSound(myCat)  -- 输出 Whiskers says: Meow!

在这个例子中,makeSound 函数可以接受任何类型的动物对象,并调用它们的 speak 方法。由于 Cat 类重写了 speak 方法,因此调用 myCat:speak 会输出猫的特定声音。

3. 面向对象设计模式 ​

在 Lua 中实现面向对象编程时,可以使用一些经典的设计模式来组织代码和解决常见问题。

单例模式 ​

单例模式确保一个类只有一个实例,并提供全局访问点。

lua
local Singleton = {}
Singleton.__index = Singleton

local instance

function Singleton:getInstance()
    if not instance then
        instance = setmetatable({}, self)
    end
    return instance
end

-- 使用单例
local singleton = Singleton:getInstance()

工厂模式 ​

工厂模式提供一个创建对象的接口,而不是直接实例化对象。

lua
local AnimalFactory = {}

function AnimalFactory:createAnimal(type, name)
    if type == "Dog" then
        return Dog:new(name)
    elseif type == "Cat" then
        return Cat:new(name)
    end
end

local myDog = AnimalFactory:createAnimal("Dog", "Rex")
local myCat = AnimalFactory:createAnimal("Cat", "Whiskers")

4. 总结 ​

面向对象编程在 Lua 中完全由表和元表实现:setmetatable 造实例,__index 挂继承,方法重写实现多态。这一页的类、单例、工厂,用的都是这几样东西。

Hello Lua