lua的面向对象实现

  百度搜索一下,给出出的解决方案和学习帖子很多,可是我还是有很多的问题!

(1)什么是面向对象?

(2)lua中怎么实现面向对象?

(3)什么样的实现既简单又能完成我的功能?

(4)一定要按照c++的方式实现类的继承吗?

  能力有限,在学习lua面向对象的时候我比较喜欢两种实现方式:

1. 简单粗暴的实现

参考[1]:参考同事的方法,如果借鉴、转载请注明

  在lua中,我们知道table是万能的一个类型,当我们用table实现一个基类和子类的时候,他们都是确确实实存在的一个个table,都是有地址的。不会说像c++一样,类定义是类定义,只有new出来才是真正可以使用的,而lua却不是这样。所以,最简单的一种方法就是,每次继承基类的时候,直接copy基类的所有内容,函数除外,其他的成员都重新复制一遍,如果是table的话重新构建一个,并且把内容拷贝过来。代码如下:

--lua面向对象:简单粗暴的实现
function copytable(tbArg)
    local tbCollsion = {}

    --local的作用域问题
    local copy
    copy = function (obj)
        if type(obj) ~= "table" then
            return obj;
        end
        --检查是否有嵌套循环的table
        if tbCollsion[obj] then
            return tbCollsion[obj];
        end

        local tbNew = {}
        tbCollsion[obj] = tbNew;
        --递归复制
        for k, v in pairs(obj) do
            tbNew[k] = copy(v);
        end
        --复制完之后,元表关系也要保留下来
        return setmetatable(tbNew, getmetatable(obj))
    end

    return copy(tbArg);
end

function inherit(tbBase, tbClass)
    --复制基类
    local tbNew = copytable(tbBase)

    local tm = {}
    tm.__index = tbClass;
    setmetatable(tbNew, tm)

    --修改tbBase为tbClass中的成员或者新增加tbClass中的成员
    if tbClass then
        for k, v in pairs(tbClass) do
            tbNew[k] = v
        end
    end

    return tbNew;
end
--使用
local tbObject = {}
local tbFruit = inherit(tbObject)
local tbApple = inherit(tbFruit)
local tbBanana = inherit(tbFruit)
local tbBanana1 = inherit(tbFruit)
local tbBanana2 = inherit(tbFruit, tbBanana1)

优点:

(1)好理解

(2)好用,不会出现共用一个table引用,导致其中一个修改影响了另外一个

(3)共享函数引用

缺点:

(1)真正意义上的面向对象,继承等概念不清晰

(2)一个子类new多个对象的概念是没有的,和继承已经混在了一起,所以如果要实现new多个对象的话,有代码冗余

2. 概念意义上的实现

参考[2]:云风的blog,如果借鉴、转载请注明

  这种从概念上实现面向对象的方法做到以下几点:

(1)有类定义和对象的概念,类定义通过new来创建对象,并且同时调用自己的构造函数

(2)子类可以访问基类的成员函数

(3)类定义不能够调用函数(除了new之外),只有对象才能调用函数

(4)构造函数调用有和c++一样的层级关系,先调用父类的构造函数,再调用子类的构造函数

--lua面向对象:概念意义上的实现
local _class={}

function class(super)
    local class_type={}
    --注意:因为重载了__newindex函数, 所以ctor不要定义为nil
    class_type.ctor=false
    class_type.super=super
    class_type.new=function(...)
            local obj={}
            --下面的块只做了一件事:依次从父类到当前子类调用构造函数ctor
            do
                local create
                create = function(c,...)
                    if c.super then
                        create(c.super,...)
                    end
                    if c.ctor then
                        c.ctor(obj,...)
                    end
                end

                create(class_type,...)
            end
            setmetatable(obj,{ __index=_class[class_type] })
            return obj
        end

    --新加成员:防止定义类调用函数
    local vtbl={}
    _class[class_type]=vtbl

    setmetatable(class_type,{__newindex=
        function(t,k,v)
            vtbl[k]=v
        end
    })

    --只有定义类修改了__newindex
    --vbtl只属于定义类
    --new出来的对象共享所有定义类的引用,但独享自己新增加的成员变量
    if super then
        setmetatable(vtbl,{__index=
            function(t,k)
                local ret=_class[super][k]
                vtbl[k]=ret
                return ret
            end
        })
    end

    return class_type
end

说明几点:

(1)只有定义类修改了__newindex
(2)vbtl只属于定义类
(3)new出来的对象共享所有定义类的引用,但独享自己新增加的成员变量

有点:

(1)概念上更加清晰,熟悉c++面向对象的很容易了解这个继承的关系

(2)写法上感觉很牛逼,做到了定义不能调用函数这一点

(3)共享函数引用

缺点:

(1)概念上清晰的成本是要更多的时间去理解

(2)虽然做到了c++类定义和对象上的概念区别,但是还是有多东西没有实现

(3)对象也可以定义自己的函数,这一点就直接打破了区分定义和对象的本源,但是价值还是有的

(4)所有new出来对象共享类定义的引用对象,包括不需要复用的函数和table。由此多个对象共享一个定义的table很是个问题!

* 针对(4),可以通过实现定义的init函数,在init函数给不同的对象初始化不同的数据,即使是table!

参考:

[1]同事

[2]http://blog.codingnow.com/cloud/LuaOO

时间: 2024-08-28 08:30:38

lua的面向对象实现的相关文章

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学习----面向对象编程

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的面向对象——类和继承

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

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

本文转载于:http://www.benmutou.com/archives/1800 在Lua中的多重继承和私密性可能用得比较少,也可能只是我个人用得比较少. 本来想偷懒不写这文章的,因为我今天刚买了个漂移板,连起步都还没学会啊,想多学一会. 咳咳,本着坚持不懈.负责到底的态度,我还是决定随便写几句~(小若:随便写几句是几吨意思啊?!) 1.多重继承之在多个类中查找一个字段 我发现这些高(shen)智(jing)商(bing)人群真的很厉害,这种技巧都能想到,很佩服. 其实多重继承没什么特别的

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

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

Lua的面向对象,封装,继承,多态

概述 我们总所周知对象是由属性和方法组成的,要用lua要描述一个对象,也必然要有这两个特性,属性和方法.lua的基本结构是table,所以Lua的类,其实都是table,因为它可以存储普通的变量又可以存储方法,我们利用table就可以描述一个对象的属性和方法. 对象 其实lua要模拟一个对象,关键就在于__index设置元表索引这块,它主要起到索引失败后该怎么办,如果它指向一张表,那么__index索引失败后,它会到这张表中去查找有没有你指定的函数或成员值,如果有,__index方法被调用时会返

【Lua】面向对象编程(一)

类和对象: account.lua   module(...,package.seeall) Account={balance=0} Account.new=function(self,o) local o=o or {} setmetatable(o,self) self.__index=self return o end Account.getBalance=function(self) return self.balance end Account.setBalance=function(