Lua实现面向对象编程
print(">>>>>>>>>面向对象思想<<<<<<<<<<<")
--[[
1.Lua语言不支持面向对象
2.自己封装成面向对象
3.使用Lua的table, 模拟类/对象
4.面向对象特性: 封装 继承 多态
]]
print(">>>>>>>>>模拟封装<<<<<<<<<<<")
Person = {
name = "张三",
age = 18,
sex = "Man",
SayHi,
}
Person.SayHi = function(s)
print("大家好, 我是" .. Person.name .. "," .. s)
end
Person.SayHi("啦啦啦")
print(">>>>>>>>>改进1<<<<<<<<<<<")
Person = {
name = "张三",
age = 18,
sex = "Man",
SayHi,
}
Person.SayHi = function(this, s)
print("大家好, 我是" .. this.name .. "," .. s)
end
Person.SayHi(Person, "啦啦啦")
a = Person
Person = nil
a.SayHi(a, "啦啦啦")
print(">>>>>>>>>改进2<<<<<<<<<<<")
Person = {
name = "张三",
age = 18,
sex = "Man",
SayHi,
}
Person.SayHi = function(this, s)
print("大家好, 我是" .. this.name .. "," .. s)
end
Person.SayHi(Person, "啦啦啦")
Person:SayHi("啦啦啦")
a = Person
a.SayHi(a,"啦啦啦")
a:SayHi("啦啦啦")
print(">>>>>>>>>变化<<<<<<<<<<<")
Person1 = {
name = "张三",
age = 18,
sex = "Man",
}
function Person1:SayHi(s) --> s表示的是参数
print("你好, 我是" .. self.name .. " !" .. s)
end
Person1:SayHi("啦啦啦")
print(">>>>>>>>><<<<<<<<<<<")
print(">>>>>>>>>类<<<<<<<<<<<")
print(">>>>>>>>><<<<<<<<<<<")
--[[
1.Lua中没有类的概念
2.我们重新定义类
把不同的表之, 作为类与对象关系.
比如: 一张表作为模板(class), 另一张表作为对象(obj)
当调用obj中的方法时, 如果obj中没有, 则从obj的原表(class)中寻找
3. Lua中, 实现该动作的语法是:
setmetatable(o, metatalbe) --> 设置o的原表为metatable.
4.
o = {}
setmetatable(o, metatable)
]]
-- Class
Person = {
name = "",
age = 0,
sex = ""
}
function Person:SayHi(s)
print("大家好, 我是" .. self.name .. "!" .. s)
end
function Person:new(name, age, sex)
o = o or {}
-- 设置派生出的对象原表是模板
setmetatable(o, self)
-- 设置模板自身的原表是自己
self.__index = self
o.name = name
o.age = age
o.sex = sex
return o
end
--调用
a = Person:new("李四",20,"男")
a:SayHi("啦啦啦")
print(">>>>>>>>>改!<<<<<<<<<<<")
Person = {
name = "",
age = 0,
sex = ""
}
function Person:SayHi( s )
print("大家好, 我是" .. self.name .. "!" .. s)
end
-- 修改名字
function Person:ChangeName( newName )
self.name = newName
end
function Person:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
-- 派生对象
a = Person:new{ name = "李四", age = 18, sex = "男"}
a:SayHi("啦啦啦")
a:ChangeName("老王")
a:SayHi("啦啦啦")
print(">>>>>>>>>继承<<<<<<<<<<<")
Human = {
name = "",
age = 0,
sex = "",
stype = ""
}
function Human:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function Human:SayHi( s )
print("大家好, 我是"..self.name.."!"..s)
end
function Human:ChangeName( newName )
self.name = name
end
-----
-- Man就是子类
Man = Human:new{}
-- 新增方法
function Man:EarnMoney( money )
print("我挣了1000块/晚")
end
function Man:SayHi( s )
print("啦啦啦")
end
-- 由Man派生出来的对象
man = Man:new{name = "lzq",age = 28,sex = "男"}
man:SayHi("啦啦")
man:EarnMoney()
print(">>>>>>>>>练习题<<<<<<<<<<<")
--[[
模拟打僵尸。需求:
定义僵尸类:
公共成员变量:类型、总血量、每次失血量
方法:初始化方法(设置僵尸种类,总血量)、被打击失血()、死亡()
定义普通僵尸类继承于僵尸类
定义有防具(路障)僵尸类继承于僵尸类:
特有成员变量:防具类型
特有方法:防具被打烂
定义铁桶僵尸类继承于有防具僵尸:
特有成员变量:弱点
特有方法:防具被磁铁吸走
1、创建普通僵尸对象,设置总血量50,每次失血量为 3
2、创建路障僵尸对象,设置总血量80,有路障时,每次失血量为 2
3、创建铁桶僵尸对象,设置总血量120,有铁桶时,每次失血量为 1
]]
Zombie = {
name = "",
Type = "",
Hp = 0,
rHp = 0,
}
function Zombie:UnderAttack()
self.Hp = self.Hp - self.rHp
if (self.Hp <= 0)
then
self:Death()
end
print(self.name .. "的当前剩余血量" .. self.Hp)
end
function Zombie:Death()
print(self.name .. "死了")
end
function Zombie:new( o )
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
-- 普通僵尸类
NormalZombie = Zombie:new{}
-- 道具僵尸
PropZombie = Zombie:new{} --> 表
PropZombie.propType = ""
function PropZombie:DestoryProp()
print(self.name .. "的防具(" .. self.propType .. ")被打烂")
end
-- 铁桶僵尸
MetaZombie = PropZombie:new{}
MetaZombie.weakness = ""
function MetaZombie:LostMeta( )
print(self.name .. "的铁桶被吸走了")
end
-- 实例化普通僵尸
normalZombie = NormalZombie :new{name = "普通僵尸", Type = 1, Hp = 50, rHp = 3}
normalZombie:UnderAttack()
-- 实例化道具僵尸
propZombie = PropZombie:new {name = "道具僵尸", Type = 2, Hp = 80, rHp = 2, propType= "路障"}
propZombie:UnderAttack()
propZombie:DestoryProp()
-- 实例化铁桶僵尸
metaZombie = MetaZombie : new{name = "铁桶僵尸", Type = 3, Hp = 120, rHp = 1, propType= "铁桶", weakness = "怕磁铁"}
metaZombie:UnderAttack()
metaZombie:DestoryProp()
metaZombie:LostMeta()
print(">>>>>>>>>说明<<<<<<<<<<<")
--[[
1.Lua可以写成多继承的
2.成员的封装. 可以通过手段将属性和方法封装成具有封装性, 但是通常没人这么做
3.Lua中单例
4.多态, 用的不多 --> 父类引用指向子类对象
]]