Lua重点:面向对象
1,封装
--面向对象类基于table来实现
--面向对象的封装
Object={}
Object.id=1
function Object:Test() --冒号 自动调用这个函数的对象(Object) 作为第一个参数传入的方法
print("id是"..self.id) --相当于将Test作为Object的成员方法
end
function Object:new()
local obj={} --建立一个用于返回的空表
self.__index=self --子表中没有的属性去元表中寻找,即obj没有去Object寻找
setmetatable(obj,self) --将Object设置为obj的元表
return obj --返回obj
end
local myObj=Object:new() --myObj相当于obj,obj中没有的元素要去Object寻找
print(myObj.id) --obj是空表,所以肯定去Object中寻找
local myObj2=Object:new() --更改myObj2对象中的id
myObj2.id=0
print(myObj.id) --myObj.id不会改变 --为什么myObj和myObj2是两个对象
print(myObj2.id) --myObj2.id发生改变 --相当于在函数中新建了一张表obj,实际上是把Object的成员赋值给空表中。
myObj:Test() --相当于从Objet中找Test方法
print("******分割符******")
--通过myObj(实例对象)调用Object(类)的成员变量。
--逆推:
--为什么要建立一个新表obj而不能直接return Objcet表?
--如下所示:myObj其实相当于一个静态类,面向对象是可以创建一个类的多个对象。
function Object:new2()
return Object
end
local myObj3=Object:new2() --myObje3就是Object
print(myObj3.id)
myObj3.id=0 --改变myObj3的id为0
local myObj4=Object:new2() --myObje4就是Object
print(myObj4.id) --myObje4的id也为0
print(myObj3.id) --myObje3的id也为0
2,继承
--继承
--写一个用于继承的方法
Object={}
Object.id=1
function Object:subClass(className)
_G[className]={} --大G表按照键值对存储所有成员 这里表示把className名字的成员设为空表
local obj=_G[className] --表示obj获得className成员的空表 将className的表赋值给obj
self.__index=self --obj找不到从Object中找
setmetatable(obj,self) --把Object设置为obj的元表
end
Object:subClass("Person") --调用冒号点函数 添加Person成员 把Person设为空表,且新建一个obj表,将Person表赋给obj。
print(Person) --实现了Person调用的成员是从Object中获得。
print(Person.id)
Object.id=2
print(Person.id) --修改Object.id的值,Person.id也会改变,说明没有创建新的对象。
print("*******分割线*******")
Object2={}
Object2.id=2
local obj2=Object2 --将Object2的表赋值给obj2
obj2.id=0 --修改obj2的id为0
print(Object2.id) --发现Object2的值也为0
print(obj2.id) --说明表是引用类型而且是强引用类型
3,多态
Object={}
Object.id=2
--封装
function Object:new()
local obj={} --建立一个用于返回的空表
self.__index=self --子表中没有的属性去元表中寻找,即obj没有去Object寻找
setmetatable(obj,self) --将Object设置为obj的元表
return obj --返回obj
end
--继承
function Object:subClass(className)
_G[className]={} --大G表按照键值对存储所有成员 这里表示把className名字的成员设为空表
local obj=_G[className] --表示obj获得className成员的空表 将className的表赋值给obj
self.__index=self --obj找不到从Object中找
obj.base=self --子类定义个base属性,base属性表示父类
setmetatable(obj,self) --把Object设置为obj的元表
end
---多态
--相同方法,不同表象 就是多态
--形同方法,不同执行逻辑 就是多态
print("*********多态**********")
Object:subClass("GameObject") --GameObject是Object的子类
GameObject.posX=0 --设置GameObject成员属性
GameObject.posY=0
function GameObject:Move() --定义GameObject的移动方法
self.posX=self.posX+1
self.posY=self.posY+1
print(self.posX)
print(self.posY)
end
GameObject:subClass("Player") --Player是GamObject的子类
function Player:Move() --定义Player的移动方法
--self.base:Move() --base是GameObject,base:Move把GameObject作为参数传进去而不是Object
self.base.Move(self) --要执行Object逻辑 不要使用冒号调用而通过.调用,然后自己传入第一个参数
end
local p1 = Player:new() --新建一个Player对象p1
p1:Move() --调用的是父类GameObject的移动方法 这样就实现了多态的重写
local p2=Player:new() --两次打印不一样,违背面向对象,因为是在共用成员变量
p2:Move()