Lua的面向对象——多重继承、私密性

本文转载于:http://www.benmutou.com/archives/1800

在Lua中的多重继承和私密性可能用得比较少,也可能只是我个人用得比较少。

本来想偷懒不写这文章的,因为我今天刚买了个漂移板,连起步都还没学会啊,想多学一会。

咳咳,本着坚持不懈、负责到底的态度,我还是决定随便写几句~(小若:随便写几句是几吨意思啊?!)

1.多重继承之在多个类中查找一个字段

我发现这些高(shen)智(jing)商(bing)人群真的很厉害,这种技巧都能想到,很佩服。

其实多重继承没什么特别的,除非两个将要被继承的类有相同的函数名和属性,否则,处理起来很简单。

无非就是在多个table中查找某个字段而已,不简单吗?Lua里的继承就是在别人的table里查找自己不存在的字段罢了。

那么,单继承与多重继承的差别也在这里,一个是只查找一个table,另一个是查找两个或以上的table。

我们就先来看看如何从2个或多个table中查找某个字段,如下代码:

function search(classes, key)
    for i = 1, #classes do
        local value = classes[i][key];
        if value ~= nil then
            return value;
        end
    end
end
local t1 = {name = "hehe"};
local t2 = {game = "who"};
print(search({t1, t2}, "game"));

这里的classes参数,是一个table,这个table里又存放了多个table,也就是我们想要继承的那些类。
而key就是要查找的字段。

只需要遍历所有的table,判断这个字段是否在某个table里,找到之后,就返回这个值。

我们的测试代码就是从t1、t2中查找game这个字段,t1、t1可以看成是两个类。

输出结果如下:

[LUA-print] who

2.多重继承之创建继承多个类的子类

刚刚的search函数很简单吧?别急着开心,那只是预热一下而已,真正创建多重继承的函数比较复杂。

如下代码:

function createClass(...)
    local parents = {...};
    local child = {};

    -- 设置类的元表
    setmetatable(child, {
        __index = function(table, key)
            return search(parents, key);
        end
    })

    -- 给类新增一个new函数,用于创建对象
    function child:new()
        o = {};
        setmetatable(o, child);
        child.__index = child;
        return o;
    end

    -- 返回这个继承了多个类的子类
    return child;
end

createClass函数就是用来创建一个继承了多个类的子类,有点小复杂,慢慢分析:

1) 参数是一个可变参数,我们要将多个被继承的类作为参数传递进来

2) parents用于保存这些被继承的类

3) 创建一个新的table——child,它就是我们想要的那个继承了多个类的子类

4) 给child设置元表,并且设置__index元方法,__index元方法可以是一个函数,当它是一个函数时,它的参数就是元表所属的table,以及要查找的字段名。

5) 我们在__index元方法函数里调用search函数,从多个父类中查找所需的字段。于是,当调用child的某个函数时,就会从各个父类中查找,这已经完成了继承的工作了。

6) 接下来就是我们所熟悉的new函数,用来创建child的子类,实现方式和上一篇所说的是一样 ,如果你忘记了,可以看看这篇文章:http://www.benmutou.com/archives/1791

7) 最后返回child,一切都完成了。

看似很复杂,其实还是对__index的应用而已。

我们赶紧来测试一下吧,如下代码:

-- 一个精灵类
    TSprite = {}
    function TSprite:hello()
        print("谁跟你hello!");
    end

    function TSprite:new()
        o = {}
        setmetatable(o, self);
        self.__index = self;
        return o;
    end

    -- 一个子弹类
    TBullet = {}
    function TBullet:fire()
        print("别动,再动我就瞄不准了!");
    end
    function TBullet:new()
        o = {}
        setmetatable(o, self);
        self.__index = self;
        return o;
    end

    -- 继承了两个类的子类
    local BulletSprite = createClass(TSprite, TBullet);

    -- 子类的对象
    local bSprite = BulletSprite:new();
    bSprite:hello();
    bSprite:fire();

这里创建了两个类:TSprite和TBullet。

然后调用createClass函数,创建一个继承了TSprite和TBullet的子类。

最后创建子类的对象,调用对象的hello和fire函数。

输出结果如下:

[LUA-print] 谁跟你hello!
[LUA-print] 别动,再动我就瞄不准了!

3.类的私密性

这里来说一个和多重继承无关的技巧,那就是私密性。

对于Java、C++等语言,我们都很熟悉,public、private、protected等关键词。

这些关键词让封装成为了可能。

然后,Lua里是没有私密这种说法的,类也是一个table,table的所有字段都是可以调用的,并没有说哪些是公有的,哪些是私有的。

如果有某些函数和属性不希望被外部调用,那么,也可以,不过这种实现方式看起来很别扭:

function createTSprite()
    local self = {name = "benmutou"};
    local function myBus()
        print("myBus是我自己的函数,你不能直接调用");
    end
    local function myGame()
        print("myGame是我自己的函数,你不能直接调用");
    end
    local function hello()
        print("hello:");
        myBus();
    end
    local function hi()
        print("hi:");
        myGame();
    end

    local function setName(newName)
        self.name = newName;
    end

    return {hello = hello, hi = hi, setName = setName};
end

我们已经不需要用到冒号来定义函数了,这个类的name、myBus、myGame都是不希望给外部直接调用的。

调用createTSprite函数后,会返回一个新的table,这个table仅仅存放了一些字段,这些字段就是能够被外部直接调用的函数或者是属性。

来看看测试代码:

 local sp = createTSprite();
    sp.hello();
    sp.hi();

输出结果如下:

[LUA-print] hello:
[LUA-print] myBus是我自己的函数,你不能直接调用
[LUA-print] hi:
[LUA-print] myGame是我自己的函数,你不能直接调用

这样,我们创建的对象就只能使用hello、hi、setName函数。

而其他的name、myBus、myGame只能通过这几个能使用的函数去调用,而不能直接调用。

这样就能完成私密性了。

不过,我个人有点迷糊,因为这已经不太像一个类的样子了。

4.结束

好了,关于面向对象的内容,暂时介绍到这里。

可能介绍的都比较基础,目的是为了巩固Lua基础。

时间: 2024-08-29 10:30:53

Lua的面向对象——多重继承、私密性的相关文章

(转载)【笨木头Lua专栏】基础补充21:面向对象——多重继承、私密性

在Lua中的多重继承和私密性可能用得比较少,也可能只是我个人用得比较少. 本来想偷懒不写这文章的,因为我今天刚买了个漂移板,连起步都还没学会啊,想多学一会. 咳咳,本着坚持不懈.负责到底的态度,我还是决定随便写几句~(小若:随便写几句是几吨意思啊?!) 笨木头花心贡献,哈?花心?不,是用心~ 转载请注明,原文地址:http://www.benmutou.com/archives/1800 文章来源:笨木头与游戏开发 1.多重继承之在多个类中查找一个字段 我发现这些高(shen)智(jing)商(

lua实现面向对象

lua实现面向对象 lua实现面向对象 实现类的定义 实现类的继承 实现类的定义 function people( name) local self = {} local function init( ... ) self.name=name end self.sayHi=function ( ... ) print("hello"..self.name) end init() return self end 实现类的继承 function Man( name) self=people

Lua 之面向对象编程

Lua 之面向对象编程 Lua并不是为面向对象而设计的一种语言,因此,仅从原生态语法上并不直接支持面向对象编程,但Lua的设计中仍然包含了很多面向对象的思想,理解它们也更有助于理解Lua自身的一些高级机制. 对象 Lua中的table就是一种对象,它可以有函数字段.在面向对象(Object Oriented)编程中,对象的方法(method)通常使用self(或this)参数标识对象自身,在Lua中也可以使用冒号(:)实现类似的功能,如下面的例子: Account = {balance=0} f

lua学习:lua实现面向对象

之前写过一篇关于lua实现面向对象的文章,借助元表和元方法实现,感觉也是有点乱. 我们可以参考cocos2d-x自己给出的类的实现,也即在luaBinding目录下extern.lua的文件中给出的实现: function class(classname, super) -- print(classname) local superType = type(super) local cls if superType ~= "function" and superType ~= "

【Lua】面向对象(二)

  多重继承: module(...,package.seeall) local function search(k,plist) for i=1,#plist do local v=plist[i][k] if v then return v end end end --多重继承 function createClass(...) local c={} local parents={...} setmetatable(c,{ __index=function(t,k) return searc

Lua学习----面向对象编程

1.类 再Lua中可以使用表和函数实现面向对象,将函数和相关的数据放置放置于同一个表中就形成了对象.例如: Measure = {width = 0, height = 0} function Measure:setWifth(v) self.width = self.width + v end function Measure:setHeight(v) self.height = self.height + v end function Measure:getMeasure() print(s

[Lua]Lua的面向对象程序设计

Lua中的表不仅在某种意义上是一种对象.像对象一样,表也有状态(成员变量):也有与对象的值独立的本性,特别是拥有两个不同值的对象(table)代表两个不同的对象:一个对象在不同的时候也可以有不同的值,但他始终是一个对象:与对象类似,表的生命周期与其由什么创建.在哪创建没有关系. local Account = {balance = 0} function Account.withdraw(v) Account.balance = Account.balance - v end --调用方法如下:

lua的面向对象实现

百度搜索一下,给出出的解决方案和学习帖子很多,可是我还是有很多的问题! (1)什么是面向对象? (2)lua中怎么实现面向对象? (3)什么样的实现既简单又能完成我的功能? (4)一定要按照c++的方式实现类的继承吗? 能力有限,在学习lua面向对象的时候我比较喜欢两种实现方式: 1. 简单粗暴的实现 参考[1]:参考同事的方法,如果借鉴.转载请注明 在lua中,我们知道table是万能的一个类型,当我们用table实现一个基类和子类的时候,他们都是确确实实存在的一个个table,都是有地址的.

Lua的面向对象——类和继承

本文转载于:http://www.benmutou.com/archives/1791 终于来了,在Lua中的面向对象编程,相信目前学习Lua的大部分人都是为了开发手机网游吧.而且基本都是奔着脚本语言的热更新特性去的,所以全脚本开发变得十分流行. 对于普及不太广的Lua(相对于C++.Java等主流语言),需要短时间上手开发游戏,对新手而言不算简单.所以大家才更习惯于继续用面向对象思想去折腾Lua吧~ 好了,不唠叨了,我最不喜欢唠叨了.(小若:是是是,你一点都不唠叨,赶紧开讲!) 1.类的对象