Lesson16_Lua基础_Lua模拟面向对象
Lua面向对象 其实都是基于表去实现的,并且请注意,我们并不是真正的去实现OOP,而是去达到想要的效果
一、封装
Object={
name="12",
age=12,
}
Object.sex=true
function Object:new()-- 冒号引出会将调用此函数的对象作为第一个参数传入,在函数内可以通过self关键字点出此参数
local obj = {} --这里是在模拟一个类创建出一个对象的new()
setmetatable(obj,self)
self.__index=self
return obj
end
local myObj=Object:new()--这里通过Object表调用了new,所以会将myObj的元表设为Object表,并且Object表的__index也被设置为Object本身,这样就可以做到myObj访问
Object表中的成员
print(myObj.name) --这里是一个name的get操作,myObj表中并没有name这一成员,但可以去访问元表中的__index指向的表,也就是Object
myObj.age=2 --执行这一语句后,你打印Object.age,会发现依然是12,这是因为Object类中并没有实现__newindex这一特定操作,其作用可见我的Lesson15文章。
--那么,myObj里并没有age这一属性,却要进行一个set(请注意是set)的操作,那么此时就相当于在myObj表外部去声明了一个新的成员age
二、继承
function Object:subClass(className)
_G[className]={} --在G表中声明一个变量(G中的全是全局变量),这样就创建了一个相应名字的表,与封装那里的new不同,封装时是不会有一个全局存在的表的
local obj=_G[className]
setmetatable(obj,self)
self.__index=self
obj.base=self--用于多态时调用保留的父类的方法,这是在外部声明的一个成员,base这里就相当于指向的父类表
end
Object:subClass("Person")--此时就已经有了一个名为Person的表,且元表为Object
print(Person.sex)--从这里也可以看出与封装时的new的区别,new是返回一个表对象,使用时得用一个变量去接收,但继承是直接创建了一个全局表,相当于已经有一个类了
local testTable=Person:new()--这里testTable的元表以及__index就会被设置为Person表了
三、多态
Object:subClass("GameObject")
GameObject.posX=0
GameObject.posY=0
function GameObject:Move( )
self.posX=self.posX+1
self.posY=self.posY+1
print(self.posX)
print(self.posY)
end
GameObject:subClass("Player")
local p1 = Player:new()
function Player:Move( )
self.base:Move()--这种写法是错误的,因为会导致传入的参数是base也就是父类表,而我们想传入的是自身
self.base.Move(self)--这里应该采取. 调用,然后传入一个self参数
end
p1:Move()

浙公网安备 33010602011771号