zoukankan      html  css  js  c++  java
  • Lua面向对象----类、继承、多继承、单例的实现

    (本文转载)学习之用,侵权立删!

    原文地址   http://blog.csdn.net/y_23k_bug/article/details/19965877?utm_source=tuicool&utm_medium=referral

    lua面向对象实现:

    一个类就像是一个创建对象的模具。有些面向对象语言提供了类的概念,在这些语言中每个对象都是某个特定类的实例。lua则没有类的概念,每个对象只能自定义行为和形态。不过,要在lua中模拟类也并不困难。

    lua中,面向对象是用元表这个机制来实现。

    首先,一般来说一个表和它的元表是不同的个体(不属于同一个表),在创建新的表时,不会自动创建元表。

    setmetatable函数:设置元表

    setmetatable( 表1 , 表2 )  将表2挂接为表1的元表,并且返回经过挂接后的表1

    __index字段:

    元表中的__index字段,是一个非常强大的字段,它为回溯查询提供支持。而面向对象的实现基于回溯查询

    当访问一个table中不存在的字段时,得到的结果为nil。但是如果这个表有元表的话,这个访问就会查找元表中的__index字段。如果没有__index字段没有赋值,那么访问结果为nil。否则,就由__index字段提供最终的结果。

    __index可以赋值为一个函数,也可以是个表。是函数时,就会调用这个函数。是表的时候,就以相同的方式重新访问这个表。

    注意:这里出现了三个表的个体,

    我们直接操作的表,称之为表A,表A的元表称之为表B,表B的__index字段赋值的表,称之为表C

    如果访问表A中的一个字段时,如果找不到,会去查看表A有没有元表B,如果有的话,就会查找B中的__index字段是否有赋值,如果赋值为表C,就会去表C中查找有没有想访问的那个字段,如果找到了,就返回那个字段,如果没有,就返回nil。

    lua面向对象--对象创建

    我们可以利用元表和元表__index字段来实现类对象的创建

    在该类的构造函数中,定义一个新的表,然后把该类(表)设置为新定义的那个表的元表的__index字段,这样,当我们用实例的对象来调用该类的某个字段的时就会去该类中查找调用,这样就实现了对象的实例化。

    例子

    class.lua

    local    class  = {}

    function  class:new()

    local self = {}     —创建新的表作为实例的对象

    setmetatable( self , {__index = class})  —设置class为对象元表的__index

    return self         —返回该新表

    end

    function class:func()

    print(“class : func”)

    end

    return class

    main.lua

    local class = require(“class”)

    s1 = class:new()   — 实例化对象s1

    s1:func()               ——->class : func

    lua面向对象--继承

    lua实现继承和实现对象实例化是一样的,利用元表和元表的__index字段来实现。

    例子

    class1.lua

    local class1 = {}

    function class1:func1()

    print(“class1 : func1”)

    end

    return class1

    class2.lua

    local class2 = {}

    local class1 = require(“class1”)

    function class2:func2()

    print(“class2 : func2”)

    end

    function class2:new()

    setmetatable(class2 , {__index = class1})  —设置class1为class2的元表的__index字段来实              现继承

    — 实例对象

    local self = {}

    setmetatable(self , {__index = class2})

    return self

    end

    return class2

    main.lua

    local class2 = require(“class2”)

    local s1 = class2:new()

    s1:func1()     ———>class1:func1

    s1:func2()     ———>class2:func2

    lua面向对象--多态

    lua支持多态

    例子:

    class1.lua

    local class1 = {x = 0,y = 0}

    function class1:new(x,y)

    -- body

    local self = {}

    setmetatable(self,class1)

    class1.__index = class1

    self.x = x

    self.y = y

    return self

    end

    function class1:test()

    print(self.x,self.y)

    end

    function class1:gto()

    return 100

    end

    function class1:gio()

    return self:gto()*2

    end

    return class1

    class2.lua

    local class2 ={}

    local class2 = require("class1")

    function class2:new(x,y)

    setmetatable(class2, class1)

    class1.__index = class2

    local self = {}

    setmetatable(self, class2)

    class2.__index = class2

    self.x = x

    self.y = y

    return self

    end

    function class2:gto()

    return 50

    end

    return class2

    main.lua

    class1 = require(“class1”)

    class2 = require(“class2”)

    s1 = class1:new()

    s2 = class2:new()

    print(s1:gio())  ——->200

    print(s2:gio())  ——>100

    —s2对象调用基类class1的gio函数,函数内部调用class2的gto函数,实现了多态。

    lua面向对象--多继承

    lua中类的多继承实现也是利用的元表和元表的__index字段,不同于对象实例化和单一继承不同的是__index字段赋值的是一个函数而不是一个基类的表。

    利用传入__index字段的函数来查找类中找不到的字段(函数中遍历该类继承的多个基类)

    查找函数:

    local function search(k,plist)

    for i = 1,#plist do

    local v = plist[i][k]

    if v then return v end

    end

    end

    —plist 为该类的基类的集合 ,k为要查找(调用继承的字段)的字段

     实现继承函数:

    local function createClass()

    local parents = {class1,class2}

    setmetatable(class3,{__index = function(t,k)

    return search(k,parents)

    end})

    end

    这样就可以实现多继承了。

    例子:

    class1.lua

    local class1 = {}

    function class1:func1()

    print("class1--func1")

    end

    return class1

    class2.lua

    local class2 ={}

    function class2:func2()

    print("class2:func2")

    end

    return class2

    class3.lua

    local class3 = {}

    local class1 = require("class1")

    local class2 = require("class2")

    local function search(k,plist)

    for i = 1,#plist do

    local v = plist[i][k]

    if v then return v end

    end

    end

    local function createClass()

    local parents = {class1,class2}

    setmetatable(class3,{__index = function(t,k)

    return search(k,parents)

    end})

    end

    function class3:func3()

    print("class3:func3")

    end

    function class3:new()

    local self = {}

    createClass()

    setmetatable(self,class3)

    class3.__index = class3

    return self

    end

    return class3

    main.lua

    local class3 = require("class3")

    local s1 = class3:new()

    s1:func1()    ————->class1:func1

    s1:func2()    ————>class2:func2

    s1:func3()    ————>class3:func3

    lua面向对象--单例模式

    lua的单例模式是利用一个全局表来实现的

    例子:

    CatManager = {}

    CatManager_mt = {__index = CatManager}  —创建一个表做实例对象的元表,__index 设置为 这个单例类

    function CatManager:new()   

    local self = {}

    setmetatable( self , CatManager_mt)  —把全局的表CatManager设置为self(新创建表)的元表的__index字段

                —每次获得单例时,创建一个self表(对象),该表继承全局表CatManager,每次修改全局表中的字段后,下次再次调用时,该字段都是已经修改过的

    return self

    end

    function CatManager:func1()

    print(“func1”)

    end

    main.lua

    require(“CatManager”)

    catManager = CatManager:new()

    一次导入进来后  ,整个程序都可以用,实现了单例的效果

     欢迎广大博友加群学习165628892(进群备注:博客)  随时提出问题解决问题!

    树欲静而风不止,子欲养而亲不待!

    2016年12月19日17:23:18

  • 相关阅读:
    OpenCV---直方图反向投影
    OpenCV---直方图的应用(均衡化和图像比较)
    ASP.NET WEB SERVICE 创建、部署与使用
    DataSet和DataTable有用的方法
    黑客网站
    局域网中工作组和域之间的差别
    索引使用原则(精)
    C# Web Service 初级教学
    Extjs下拉多选框
    如何在UltraEdit中高亮显示PB代码
  • 原文地址:https://www.cnblogs.com/unityzc/p/6198278.html
Copyright © 2011-2022 走看看