lua的面向对象编程

首先我们去了解一下类,一个类就是一个创建对象的模具,实际上,lua中不存在类这个概念,我们都是去模拟类。在lua中,要表示一个类,只需创建一个专用作其它对象的原型。我们在lua的面相对象,就是使用table,元表以及元方法,我们现在看一下具体事怎么做的:

我们现在有两个对象a和b,现在想b作为a的原型,只需编写下面代码即可:

setmetatable(a,{__index = b})

我们前面有讲过__index,编写完这段代码之后,当lua执行了a没有的操作的时候,就会去b中查询。实际上我们也可以称b事对象a的类;我们要创建一个对象,必须要有一个原型,这就是“类”。如下:

local man = {num = 0}

现在我们有原型类,接着我们使用这个原型创建一个“实例”,首先我们先编写man的new函数:

function man:new(o)
    o = o or {}    --如果o为nil,则将o复制为{}
    setmetatable(o,self)
    self.__index = self
    return o
end

function man:sayhi()
    self.num = self.num + 1
    print("已经打招呼的人" .. self.num)
end

当我们调用man的new函数的时候,self就相当于man。接着我们来使用man的new函数来创建一个实例:

local tom = man:new()
tom:sayhi()
tom:sayhi()

输出:

已经打招呼的人1
已经打招呼的人2

我们来看一下上面的代码如何工作的,首先使用man的new函数去创建一个新的实例对象,并将man作为新的实例对象tom的元表。当我们调用tom:sayhi()时,lua就会去查找tom是否有sayhi这个字段,没有的话就去搜索它的元表,调用的结果实际上是:

getmetatable(tom).__index(sayhi(tom))

而tom的元表是man,man的__index也是man,上面的写法实际上也是:

man.sayhi(tom)

实际上,我们上面也是涉及到了继承的(sayhi函数)。接着我们来探讨一下lua的多继承:

我们可以可以设置子类的metatable为父类,并将父类的__index设置为其本身来实现单继承。而多继承也是一样的道理,不同的是单继承中如果子类没有对应的字段,则只需在一个父类中寻找这个不存在的字段,而多继承则是需要在多个父类中寻找。

由于多继承需要在多个父类中寻找,所以我们不能像单继承那样,直接指向__index为某个父类,而是应该指定__index为一个函数,在这个函数中指定搜索不存在的字段的规则。这样便可以实现多继承。我们看一下下面的例子:

-- 在多个父类中查找字段k
local function search(k, pParentList)
    for i = 1, #pParentList do
        local v = pParentList[i][k]
        if v then
            return v
        end
    end
end

function createClass(...)
    local c = {} -- 新类
    local parents = {...}

    -- 类在其元表中搜索方法
    setmetatable(c, {__index = function (t, k) return search(k, parents) end})

    -- 将c作为其实例的元表
    c.__index = c

    -- 为这个新类建立一个新的构造函数
    function c:new(o)
        o = o or {}
        setmetatable(o, self)

        -- self.__index = self 这里不用设置了,在上面已经设置了c.__index = c
        return o
    end

    -- 返回新的类(原型)
    return c
end

-- 一个简单的类CA
local CA = {}
function CA:new(o)
    o = o or {}
    setmetatable(o, {__index = self})
    self.__index = self
    return o
end

function CA:setName(strName)
    self.name = strName
end

-- 一个简单的类CB
local CB = {}
function CB:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end

function CB:getName()
    return self.name
end

-- 创建一个c类,它的父类是CA和CB
local c = createClass(CA, CB)

-- 使用c类创建一个实例对象
local objectC = c:new{name = "Jelly"}

-- 设置objectC对象一个新的名字
objectC:setName("JellyThink")
local newName = objectC:getName()
print(newName)

注:

  1. 使用createClass创建了一个类(原型),将CA和CB设置为这个类(原型)的父类(原型);在创建的这个类(原型)中,设置了该类的__index为一个search函数,在这个search函数中寻找在创建的类中没有的字段;
  2. 创建的新类中,有一个构造函数new;这个new和之前的单继承中的new区别不大,很好理解;
  3. 调用new构造函数,创建一个实例对象,该实例对象有一个name字段;
  4. 调用object:setName(“JellyThink”)语句,设置一个新的名字;但是在objectC中没有这个字段,怎么办?好了,去父类找,先去CA找,一下子就找到了,然后就调用了这个setName,setName中的self指向的是objectC;设置以后,就相当于修改了objectC字段的name值;
  5. 调用objectC:getName(),objectC还是没有这个字段。找吧,CA也没有,那就接着找,在CB中找到了,就调用getName,在getName中的self指向的是objectC。所以,在objectC:getName中返回了objectC中name的值,就是“JellyThink”。

其实lua的类就是创建一个table,然后为table绑定几个方法,绑定几个对象。然后在通过元表与元方法的一些操作从而完成lua的面相对象编程。

时间: 2024-08-03 12:20:51

lua的面向对象编程的相关文章

Lua 之面向对象编程

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

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】面向对象编程(一)

类和对象: 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(

Lua中面向对象编程的理解

模块 模块是一个独立的空间,一个独立的环境,访问模块成员需要先require,并使用"模块名.成员名称"的格式访问.注意:模块是一个table. 类 在lua中所有对象都是一个table,类也是一个table,但类应该是一个只读的table,类的定义是通过创建一个模块实现的. lua代码: module("Student",package.seeall) function study(self) end 在调用module方法时添加package.seeall参数的

Lua面向对象编程

Lua中的table就是一种对象,看以下一段简单的代码: 1 local tb1 = {a = 1, b = 2} 2 local tb2 = {a = 1, b = 2} 3 local tb3 = tb1 4 5 if tb1 == tb2 then 6 print("tb1 == tb2") 7 else 8 print("tb1 ~= tb2") 9 end 10 11 tb3.a = 3 12 print(tb1.a) 上述代码会输出tb1 ~= tb2.

Lua语言基础汇总(12)-- Lua中的面向对象编程

简单说说Lua中的面向对象 Lua中的table就是一种对象,看以下一段简单的代码: 1 2 3 4 5 6 7 8 9 10 11 12 local tb1 = {a = 1, b = 2} local tb2 = {a = 1, b = 2} local tb3 = tb1   if tb1 == tb2 then      print("tb1 == tb2") else      print("tb1 ~= tb2") end   tb3.a = 3 pri

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

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

面向对象编程

面向对象:类,属性,方法 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的"对象",每个对象都拥有相同的方法,但各自的数据可能不同. 仍以Student类为例,在Python中,定义类是通过class关键字: class Student(object): pass class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下

python面向对象编程

java和c#只支持面向对象编程,python即可支持面向对象也可以支持函数式编程. 面向对象两个重要的概念:  1.类 2.对象 函数式 def sendemail(email,msg):            函数 print("8888") 面向对象 class Myclass: def sendmail(self,email,msg):      函数定义在类中第一个参数必须是self print("8888")              函数在类中定义叫方