Lua 面向对象

最后更新于 2024-09-11 453 次阅读


类设计

Lua并不是面向对象编程语言,Lua中的面向对象都只是对真正的面向对象的一种模拟,Lua之所以能够实现这种模拟,源于Lua中的三剑客:table,metatable,__index。

local Account = { balance = 1000 }

function Account.Withdraw(self, money)

   self.balance = self.balance - money

end

local aa = Account
aa.Withdraw(aa, 100)
print(aa.balance)
print(Account.balance)

aa:Withdraw(100)
print(aa.balance)
print(Account.balance)

输出结果:
900
900
800
800

这并不是真正的对象,如此创建会形成闭包,同时修改一个包里的数据

Class = { x=0, y=0 }
Class.__index = Class

function Class:new(x,y)
    local self = { }  
    setmetatable(self, Class)  
    self.x = x   
    self.y = y
    return self 

end

function Class:print()
    print(self.x, self.y)
end

function Class:plus()
    self.x = self.x + 1
    self.y = self.y + 1
end

a = Class:new(10, 20)
a:print()
b = Class:new(11, 23)

b:print()
b:plus()
b:print()
a:print()

输出结果:
10 20
11 23
12 24
10 20

将自己的元表指向自己,并设置。如此就可以通过元表,即使新创建的对象内部变量在自己的元表内管理,形成了类对象的功能,对象和对象之间互相独立。

Lua 继承

基类

--类的属性
local Vehicle = {
    wheels = 4,
    speed = 100,
    color = “b”
}

--有了这一句才能算是一个类,因为这一句实现了实例和类之间的关联性
Vehicle.__index = Vehicle

--构造函数
function Vehicle:New(wheels, speed, color)
    local obj = {}
    setmetatable(obj, self) --这里和上面的__index是遥相呼应的
    obj.wheels = wheels
    obj.speed = speed
    obj.color = color
 
    return obj
end

--基类的方法
function Vehicle:getSpeed()
    print(self.speed)
end

function Vehicle:setSpeed(x)
    self.speed = x
end

function Vehicle:speedPluss()
    self.speed = self.speed + 1
end 

实现继承

local Bicycle = { engine = 1 }

setmetatable(Bicycle, Vehicle) --这里就实现了Bicycle对Vehicle的继承
Bicycle.__index = Bicycle      --这样就实现了一个类,以便Bicycle的每个实例都到Bicycle进行查找

function Bicycle:New(engine)
    local obj = {}
    obj = Vehicle:New(2, 10, "r")
    obj.engine = engine --除了继承基类成员外,添加自己成员
 
    setmetatable(obj, self) --使得Bicycle的每个实例都与Bicycle挂钩
 
    return obj
end

--对父类方法的重载

function Bicycle:setSpeed(s)
    self.speed = s
 
end

function Bicycle:getSpeed()
    print(self.speed)
end 

--创建Bicycle的两个对象

ob1 = Bicycle:New(2)
ob2 = Bicycle:New(3)

ob1:printAll()
ob2:printAll()

ob1:setSpeed(15)
ob2:speedPluss()

ob1:printAll()
ob2:printAll()

输出的结果:

10,2,r,2
10,2,r,3
15,2,r,2
11,2,r,3

Lua 多态

在Lua中没有类型的概念,不存在像c++中那样用基类的引用或指针来指向派生类,因此,在Lua中模拟的多态只能说是:基类生成的对象会调用基类的方法,如果它的子类重写了该方法,那么子类生成的对象就会调用子类的这个方法,而不会去调用基类中的方法。