《Cocos2d-x之lua核心编程(第二版)》示例代码注释详解 3


请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com

用表模拟面向对象编程中的类和对象

1 用元表实现一个People类

People = {age = 18}

--[[
等同于这样的声明方式:
function People.new(self) self就是People表本身
--]]
function People:new()
    local p = {}             -- 生成一个表p
    setmetatable(p, self)    -- 表p的元表设置为表People
    self.__index = self      --[[ 表People的__index值就是__People本身。前文说到,__index对应的值可以是
                                  一个table也可以是一个table。现在以一个table作为__index的值 --]]
    return p
end

function People:growUp()
    self.age = self.age + 1
    print(self.age)
end

-- 测试
p1 = People:new()

--[[
p1:growUp()的调用等价于:p1.growUp(p1)。这个语句的执行可以分解为以下的一些步骤:

1 首先要拿到函数p1.growUp。从People:new函数中可以知道:p1就是People:new函数中的p,一开始就是一个空表,
但这个空表p的元表就是表People,且空表p的元表People表的__index方法就是它自己,这也就是说。虽然p表是一个空表,
但是当执行到p1.growUp时,会查找执行到People.growUp的函数去执行之。

2 得到了People.growUp函数之后执行值,这里p1:growUp()的调用方式是等价于People.growUp(p1)。在growUp函数内部
当执行到self.age = self.age+1语句时,一开始的p1表中没有age项目,但执行语句后,首先会从People表中复制一份age项到
p1表,然后再对p1自身的age项加1.所以输出19。p2也是遵循这个“复制一份age项到p2表”的操作,故而最后也是输出19
--]]
p1:growUp() -- 输出19

p2 = People:new()
p2:growUp() -- 输出19

2 在People类的基础上定义Man类

People = {age = 18}

function People:new()
    local p = {}
    setmetatable(p, self)
    self.__index = self
    return p
end

function People:growUp()
    self.age = self.age + 1
    print("People's growUp:" .. self.age)
end

--[[
表Man等同于类People的一个实例对象。Man:growUp调用了People.growUp(self)函数。
执行Man:growUp函数,输出的语句为:
People's growUp:19
--]]
Man = People:new()
Man:growUp()

--[[
表Man可以视为类People的一个实例对象,但也可以视为一个类Man。下面的语句定义了growUp
函数,其实也就是等同于重载了People类的growUp函数了
--]]
function Man:growUp()
    self.age = self.age + 1
    print("Man's growUp:" .. self.age)
end

-- 测试
man1 = Man:new() --[[ 执行的是People.new函数,但这时候,表man1的元表为表Man,注意这时候
                  的表Man中已经有age属性了,而且age值为19--]]
man1:growUp() --[[ 表man1执行的是Man.growUp(self)函数,所以执行这函数输出为:
                 Man's growUp:20 --]]

3 同一个表先后对应于两个不同的对象实例

People = {age = 18}

function People:new()
    local p = {}
    setmetatable(p, self)
    self.__index = self
    return p
end

function People:growUp()
    self.age = self.age + 1
    print("People's growUp:" .. self.age)
end

Man = People:new()

function Man:growUp()
    self.age = self.age + 1
    print("Man's growUp:" .. self.age)
end

--[[
People:new()方法和Man:new()方法都是两个不同的实例对象,且Man表自身没有执行过Man:growUp方法。
因此。先后两次的person:growUp方法的执行,分别显示了以下的两个语句:
People's growUp:19
Man's growUp:19
--]]
person = People:new()
person:growUp()
person = Man:new()
person:growUp()