类设计
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中模拟的多态只能说是:基类生成的对象会调用基类的方法,如果它的子类重写了该方法,那么子类生成的对象就会调用子类的这个方法,而不会去调用基类中的方法。
Comments NOTHING