lua继承

quick-cocos2dx lua里对class的定义

在quick-cocos2dx里, 通过class() 函数进行类的定义

下面贴出quick-cocos2d-x-2.2.1-rc 里 class()的源码

 
function class(classname, super)
    local superType = type(super)
    local cls
 
    if superType ~= "function" and superType ~= "table" then
        superType = nil
        super = nil
    end
 
    if superType == "function" or (super and super.__ctype == 1) then
        -- inherited from native C++ Object
        cls = {}
 
        if superType == "table" then
            -- copy fields from super
            for k,v in pairs(super) do cls[k] = v end
            cls.__create = super.__create
            cls.super    = super
        else
            cls.__create = super
            cls.ctor = function() end
        end
 
        cls.__cname = classname
        cls.__ctype = 1
 
        function cls.new(...)
            local instance = cls.__create(...)
            -- copy fields from class to native object
            for k,v in pairs(cls) do instance[k] = v end
            instance.class = cls
            instance:ctor(...)
            return instance
        end
 
    else
        -- inherited from Lua Object
        if super then
            cls = {}
            setmetatable(cls, {__index = super})
            cls.super = super
        else
            cls = {ctor = function() end}
        end
 
        cls.__cname = classname
        cls.__ctype = 2 -- lua
        cls.__index = cls
 
        function cls.new(...)
            local instance = setmetatable({}, cls)
            instance.class = cls
            instance:ctor(...)
            return instance
        end
    end
 
    return cls
end

我们先考虑最简单的情况, 在没有继承的情况下定义一个类ClassA

--ClassA.lua
local ClassA = class("ClassA")
ClassA.field1 = "this is field1"
return ClassA
--main.lua
local ClassA = require("ClassA")
local InstanceA = ClassA.new()

这种情况下, ClassA 跟InstanceA的关系如下图

InstanceA的metatable为ClassA, 而且ClassA.__index = ClassA, 因此,对于InstanceA找不到的属性, 将在ClassA里进行查找。 需要注意的是,ClassA里的属性比如field1, 是相当于类变量的概念,所有实例都公用该属性,并非各自维护该字段的拷贝。

下面如果要再定义ClassB, 从ClassA 进行继承

--ClassB.lua
local ClassB = class("ClassB", require("ClassA"))
 
return ClassB

这种情况下, ClassB 跟InstanceB, ClassA的关系如下图

同理,InstanceB里没有定义的属性, 将首先在ClassB里进行搜索, 如果ClassB里搜不到, 将向上追寻到ClassA里。

上面考虑的都只是针对纯Lua类, 在实际情况中, 我们需要对C++里生成的对象(userdata)进行扩展, 可以如下定义

--ClassC.lua
local ClassC = class("ClassC", function() 
     --调用C++接口创建一个原生对象(userdata), 并且给该对象绑定一个peer(table), 这里我们以创建一个CCNode为例
     local node = CCNode:create()  --原生对象(userdata)
     local peer = {}              
     tolua.setpeer(node , peer )
     return node
end)
 
return ClassC

ClassC跟InstanceC的关系如下图

在调用InstanceC(实际上是一个userdata)上的某个方法时, 首先会先去这个userdata绑定的peer这个table里寻找这个方法,如果找不到才会去c++那层调用。

所以我们可以通过给peer添加几个方法从而实现给InstanceC(userdata)扩展方法, 实际情况上也确实如此,在quick里,有几个专门的类,CCNodeExtend,CCLayerExtend,CCSceneExtend,CCSpriteExtend, 使用比如 CCNodeExtend.extend(someCCNodeInstance), 可以生成一个特殊的peer, 这个peer的metatable为CCNodeExtend, 这样我们就可以在someCCNodeInstance上调用CCNodeExtend定义了而原本CCNode没有的方法, 从而实现扩展。

下面再考虑ClassD从ClassC继承的情况

--ClassD.lua
local ClassD = class("ClassD", require("ClassC"))
 
 
return ClassD

关系图:

Comments

发表评论

### Lua 中实现类的继承Lua 中,可以通过表和元表机制来模拟面向对象编程中的类及其继承关系。对于继承自 `Super` 的子类创建,主要依赖于设置合适的环境以及利用构造器(ctor)函数完成初始化工作。 下面是一个具体的例子展示如何让一个名为 `SubClass` 的类继承另一个称为 `Super` 的父类: ```lua -- 定义超级类 Super local function Super() local class_type = {} -- 构造函数 function class_type:new(...) local instance = setmetatable({}, { __index = self }) if type(self.ctor) == "function" then self.ctor(instance, ...) end return instance end -- 初始化构造器 function class_type:ctor(x) self.value = x or 0 end -- 方法定义 function class_type:getValue() return self.value end return class_type end -- 创建 SubClass 并使其继承自 Super local function SubClass(super_class) local subclass_instance = super_class.new() -- 使用super_class的新建实例作为模板 local class_type = {} -- 设置 metatable 和索引指向 superclass setmetatable(class_type, { __index = super_class, __call = function(cls, ...) return cls:new(...) end }) -- 自定义构造器覆盖或扩展超类的行为 function class_type:ctor(x) super_class.ctor(self,x*2) -- 调用父级构造器并传递参数 print("SubClass constructor called.") end -- 添加新的方法到子类中 function class_type:addValue(addition) self.value=self.value+addition end return class_type end -- 测试代码 local superClassInstance=Super():new(10)[^1] print("Super Value:",superClassInstance.getValue()) local subClassInstance=SubClass(Super):new(5)[^2] print("Sub Class Initial Value After Constructor Called:",subClassInstance.getValue()) subClassInstance:addValue(7) print("After Adding Value In SubClass Method:",subClassInstance.getValue()) ``` 在这个示例里,先定义了一个简单的基类 `Super` ,它有一个属性 `value` 及其获取的方法 `getValue()` 。接着定义了派生类 `SubClass` 来继承这个基础结构,并增加了自己的行为——即修改后的构造器逻辑和新增加的方法 `addValue()` 。最后通过测试部分验证了这种设计模式的有效性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值