• Lua的面向对象程序设计


    Account={balance=0}
    function Account.withdraw(self,v)
        self.balance=self.balance-v
    end
    
    a={balance=0,withdraw=Account.withdraw}
    a.withdraw(a,260)
    
    --面向对象语言常使用self参数,lua提供了通过使用冒号操作符来隐藏self参数的声明
    
    function Account:withdraw(v)
        self.balance=self.balance-v
    end
    a:withdraw(100.0)
    --冒号的效果相当于在函数定义和函数调用的时候,增加一个额外的隐藏参数
    --我们可以使用dot语法定义函数而用冒号语法调用函数,反之亦然,只要我们正确的处理好额外的参数.
    --dot语法定义时要加上self参数,调用时要传入相应的对象,冒号语法不用self参数,调用时也不需要相应的参数对象

    Lua中对象没有类,每个对象有一个原型prototype,当调用不属于对象的某些操作时,会最先会到prototype中查找这些操作。

    Account={balance=0}
    
    function Account:withdraw(v)
        self.balance=self.balance-v
    end
    
    function Account:deposit(v)
        self.balance=self.balance+v
    end
    
    function Account:new(o)--返回一个子对象
        o=o or {}
        setmetatable(o,self)--Account成为o的原型
        self.__index=self
        return o
    end
    
    a=Account:new{balance=0}
    print(a.balance)--输出0
    a:deposit(100.00)
    print(a.balance)--输出100

    Account={balance=0}
    
    function Account:withdraw(v)
        if v>self.balance then error"insufficient funds" end 
        self.balance=self.balance-v
    end
    
    function Account:deposit(v)
        self.balance=self.balance+v
    end
    
    function Account:new(o)
        o=o or {}
        setmetatable(o,self)--Account成为o的原型
        self.__index=self
        return o
    end
    
    SpecialAccount=Account:new()
    
    function SpecialAccount:getLimit()
        return self.limit or 0
    end
    --子类可以重定义从父类中继承来的方法
    function SpecialAccount:withdraw(v)
        if v-self.balance>=self:getLimit() then
            error"insufficeint funds"
        end
        self.balance=self.balance-v
    end
    
    
    s=SpecialAccount:new{limit=1000.00}
    
    function s:getLimit()
        return self.balance*0.1
    end
    
    s:withdraw(200.0)--该调用将运行SpecialAccount的withdraw方法,但是当
    --方法调用self:getLimit时,最后的定义被触发.

    多重继承:将函数用作__index。当一个表的metatable存在一个__index函数时,如果lua调用一个原始表中不存在的函数,Lua将调用这个__index指定的函数,这样可以用__index实现在多个父类中查找子类不存在的域。

    --原型,相当于父类
    Account={money=0}
    
    function Account:save(v)
        self.money=self.money+v
    end
    
    function Account:spend(v)
        self.money=self.money-v
        if self.money<0 then
            error"there is not enough money"
        end
    end
    
    function Account:new(o)
        o=o or {}
        setmetatable(o,self)
        self.__index=self--首先在o的原型中查找,然后在原型的__index中查找
        return o
    end
    --k是缺少的域,plist是table,其元素也是table
    function search(k,plist)
        for i=1,table.getn(plist) do
            local v=plist[i][k]
            if v then return v end
        end
    end
    
    function createClass(...)
        local c={}
        --__index是函数时,Lua将table和其缺少的域作为参数调用这个函数
        setmetatable(c,{__index=function(t,k) print(t,k) return search(k,arg) end})
        c.__index=c
        function c:new(o)
            o=o or {}
            setmetatable(o,c)
            return o
        end
        return c
    end
    
    Named={}
    
    function Named:getname()
        return self.name
    end
    
    function Named:setname(s)
        self.name=s
    end
    
    NamedAccount=createClass(Account,Named)
    account=NamedAccount:new{name="paul"}
    print(NamedAccount)
    print(account:getname())
    
    --[[
    table: 0039C988
    table: 0039C988    getname
    paul
    ]]

    私有性

    function newAccount(initialBalance)
        --存储在self表中的部分都是私有的
        local self={balance=initialBalance}
        
        local withdraw=function(v)
            self.balance=self.balance-v
        end
        
        local deposit=function(v)
            self.balance=self.balance+v
        end
        
        local getBalance=function() return self.balance end
    
        return {
            withdraw=withdraw,
            deposit=deposit,
            getBalance=getBalance
        }
    end
    
    instance=newAccount(100)
    print(instance.getBalance())
    instance.withdraw(40)
    print(instance.getBalance())

    single-method的对象实现方法:当对象只有一个单一的方法时,可以将这个单一的方法作为对象返回

    function newObject(value)
        return function(action,v)
            if action=="get" then return value
            elseif action=="set" then value=v
            else error("invalid action")
            end
        end
    end
    --每一个对象是一个单独的闭包,代价比表小得多,这种方式没有继承但有私有性:访问
    --对象状态的唯一状态是通过它的内部方法
    d=newObject(0)--d这个对象是newObject返回的单一方法
    print(d("get"))--0
    d("set",10)
    print(d("get"))--10
  • 相关阅读:
    归并排序处理复杂对象例子
    Java归并排序的递归与非递归实现
    Java实现一个双向链表的倒置功能
    Node<T> 的作用
    Tomcat控制台总是打印日志问题的解决办法
    git回滚部分文件到某个版本
    ios-deploy was not found
    Ionic3的http请求如何实现token验证,并且超时返回登录页
    Ionic开发遇到的坑整理
    使用gradle命令代替CUBA Studio,启动项目
  • 原文地址:https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/4459735.html
Copyright © 2020-2023  润新知