通过表Table来实现面向对象
封装
--面向对象、类 都是基于表Tbale来实现的
Object = {}
Object.id = 1
function Object:Test()
print(self.id)
end
--冒号 会将调用这个函数的对象作为第一个参数传入
function Object:new()
--self 代表的是 默认传入的第一个参数
--返回一个新的表对象(模拟实例化)
local obj = {}
setmetatable(obj,self)--self代表Object,因为Object是调用者
self.__index = self
return obj
end
local myObj = Object:new();
print(myObj)
print(myObj.id) --=>myObj中没有id属性,去元表Object的__index指定的表Object中查找,得到1
myObj:Test() --=> 1
myObj.id = 2 --=>对myObj这张表增加一个id,值为2
print(myObj.id) --=>此时myObj中存在id属性,因此打印的是myObj中的id
myObj:Test() --=>2
print(Object.id) --=> 1 元表的值没有改变
继承
--核心:用_G创建一个新的Table(类),基于元表实现继承
function Object:subClass(className)
--_G是存储已申明全局变量的Table
--申明一张新的Table
_G[className] = {}
local obj = _G[className]
setmetatable(obj,self)
self.__index = self
--定义一个base属性代表父类
obj.base = self
end
Object:subClass("Person")
print(Person)
print(Person.id) --=> 1
local p1 = Person:new()
print(p1.id) --=> 1(p1没有,找元表Object的__index——Object的id)
p1.id = 2
print(p1.id) --=> 2(p1里有id,直接输出p1的id)
print(Person.id) --=> (Person没有id,找元表Object的__index——Object的id)
p1:Test(); --=> 2
多态
Object:subClass("GameObject")
GameObject.posX = 0
GameObject.posY = 0
function GameObject:Move()
self.posX = self.posX + 1
self.posY = self.posY + 1
print("x:"..self.posX)
print("y:"..self.posY)
end
GameObject:subClass("Player") --申明一个类Player,继承GameObject
function Player:Move()
--base指的是GameObject,在继承时赋值
--这种方法调用,相当于把基类作为第一个参数传入方法
--导致更新的是GameObject中的属性
--应该避免把基类表传入到方法中
--XXXX self.base:Move() XXXX
--如果需要执行父类逻辑,需要用.调用,将自己作为第一个参数传入
self.base.Move(self)
end
local p1 = Player:new() --实例化
p1:Move()
local p2 = Player:new()
p2:Move()
评论(0)
暂无评论