lua面向对象

是的,Lua的表中可以存储函数,这是Lua实现面向对象编程的核心机制。以下是几种常见的方式:

## 1. 基础:表存储函数

```lua
-- 创建表并存储函数
local person = {
name = "张三",
age = 25,

-- 在表中直接定义函数
sayHello = function(self)
print("你好,我是 " .. self.name)
end,

-- 另一种定义方式
introduce = function(self)
print("我叫" .. self.name .. ",今年" .. self.age .. "岁")
end
}

-- 调用函数(需要使用冒号语法或显式传递self)
person:sayHello() -- 冒号语法,自动传递self
person.introduce(person) -- 点语法,需要显式传递self
```

## 2. 实现简单的类(使用元表)

```lua
-- 1. 定义类(构造函数)
local Person = {}

-- 2. 创建类的方法
function Person:new(name, age)
local obj = {
name = name or "无名",
age = age or 0
}

-- 设置元表,实现继承
setmetatable(obj, { __index = Person })

return obj
end

-- 3. 定义类的方法
function Person:sayHello()
print("你好,我是 " .. self.name)
end

function Person:introduce()
print("我叫" .. self.name .. ",今年" .. self.age .. "岁")
end

function Person:setAge(newAge)
self.age = newAge
print(self.name .. "的年龄改为" .. newAge)
end

-- 4. 使用类
local p1 = Person:new("李四", 30)
local p2 = Person:new("王五", 25)

p1:sayHello() -- 输出:你好,我是 李四
p2:introduce() -- 输出:我叫王五,今年25岁
p1:setAge(31) -- 输出:李四的年龄改为31
```

## 3. 继承的实现

```lua
-- 基类
local Animal = {}

function Animal:new(name)
local obj = {
name = name,
type = "动物"
}
setmetatable(obj, { __index = Animal })
return obj
end

function Animal:speak()
print(self.name .. "发出了声音")
end

-- 子类
local Dog = {}

-- 设置继承(Dog 继承自 Animal)
setmetatable(Dog, { __index = Animal })

function Dog:new(name)
local obj = Animal:new(name) -- 调用父类构造函数
obj.type = "狗"

-- 重写元表,保持继承链
setmetatable(obj, { __index = Dog })
return obj
end

-- 重写父类方法
function Dog:speak()
print(self.name .. "汪汪叫!")
end

-- 子类特有方法
function Dog:wagTail()
print(self.name .. "摇尾巴~")
end

-- 使用
local myDog = Dog:new("旺财")
myDog:speak() -- 输出:旺财汪汪叫!
myDog:wagTail() -- 输出:旺财摇尾巴~
print(myDog.type) -- 输出:狗
```

## 4. 更简洁的类定义(使用闭包)

```lua
-- 使用闭包封装私有变量
function createCounter()
local count = 0 -- 私有变量

local counter = {}

function counter:increment()
count = count + 1
return count
end

function counter:decrement()
count = count - 1
return count
end

function counter:getValue()
return count
end

return counter
end

local counter1 = createCounter()
print(counter1:increment()) -- 输出: 1
print(counter1:increment()) -- 输出: 2

local counter2 = createCounter()
print(counter2:getValue()) -- 输出: 0 (独立实例)
```

## 5. 实用的类模板

```lua
-- 通用的类创建函数
function class(base)
local cls = {}

-- 如果有基类,设置继承
if base then
setmetatable(cls, { __index = base })
cls.super = base
end

-- 类的元表
cls.__index = cls

-- 构造函数
function cls:new(...)
local instance = setmetatable({}, cls)

-- 如果有初始化函数,调用它
if cls.init then
cls.init(instance, ...)
end

return instance
end

return cls
end

-- 使用模板创建类
local Shape = class()

function Shape:init(x, y)
self.x = x or 0
self.y = y or 0
end

function Shape:move(dx, dy)
self.x = self.x + dx
self.y = self.y + dy
end

-- 继承
local Circle = class(Shape)

function Circle:init(x, y, radius)
-- 调用父类初始化
self.super.init(self, x, y)
self.radius = radius or 1
end

function Circle:area()
return math.pi * self.radius * self.radius
end

-- 使用
local circle = Circle:new(10, 20, 5)
print("面积:", circle:area()) -- 输出: 面积: 78.539816339745
circle:move(5, 5)
print("新位置:", circle.x, circle.y) -- 输出: 新位置: 15 25
```

## 要点总结

1. **表存储函数**:Lua的表可以存储任何类型的值,包括函数
2. **冒号语法**:`obj:method()` 等价于 `obj.method(obj)`,会自动传递`self`
3. **元表实现继承**:通过设置`__index`元方法实现原型继承
4. **封装**:可以使用闭包实现私有变量
5. **多态**:通过重写父类方法实现多态

Lua的面向对象是原型式的,非常灵活。虽然不像Java/C++那样严格,但完全能满足日常开发需求。

posted on 2025-12-29 09:48  小沙盒工作室  阅读(2)  评论(0)    收藏  举报