zoukankan      html  css  js  c++  java
  • 【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(self,money)
        self.balance=money
    end
    
    Account.withdraw=function(self,money)
        if money<0 then
        error("<Account.deposit> money must > 0")
        else
        if money > self.balance then
            error("<Account.deposit> no enough balance")
        end
        self.balance=self.balance-money
        end
    end
    
    Account.deposit=function(self,money)
        if money <0 then
        error("<Account.deposit> money must > 0")
        end
        self.balance=self.balance+money
    end
    
    Account.__tostring=function(self)
        str=os.date("%y/%m/%d %H:%M:%S",os.time())
        str=string.format("%s
    Balance:%s",str,self.balance)
        return str
    end

     

    注:

           Lua检测到没有的字段时,但在其元表中有一个__index字段,那么Lua会调用这个__index元方法,并返回结果,__index元方法可以使函数或者是table,当元方法是一个函数时,Lua以table和不存在的key做为参数来调用该函数,当元方法是一个table时,Lua重新访问这个table。

        上述代码,当调用Account:new 时,self等于Account,因此可以直接使用Account来代替self,当引入类的继承时,使用self更加准确。

     

    继承:

    specialAccount.lua 

    module(...,package.seeall)
    
    SpecialAccount=MAccount.Account:new({limit=1000.0})
    
    SpecialAccount.getLimit=function(self)
        return self.limit
    end
    
    SpecialAccount.withdraw=function(self,money)
        if money <0 then
        str="<SpecialAccount.withdraw> money must > 0"
        Logger:error(str)
        error(str)
        end
    
        if money > self:getLimit() then
        Logger:warn("<SpecialAccount.with> withdraw > limit")
        return
        end
        self.balance=self.balance-money
    end
    
    SpecialAccount.__tostring=function(self)
        str=string.format("%s
    Limit:%d",MAccount.Account.__tostring(self),self.limit)
        return str
    end

    说明:

        SpecialAccount继承了Account的所有函数和变量,在执行SpecialAccount的new函数,它的self参数表示为SpecialAccount,因此执行以下语句:

    clipboard[3]

         s表示的元表为SpecialAccount,而SpecialAccount中的__index值也是SpecialAccount,s继承自SpecialAccount,而SpecialAccount又继承自Account,Lua在s中找不到deposit字段时,会查找SpecialAccount,如果仍找不到deposit字段,就会查找Account,最终会在那里找到deposit字段。

        SpecialAccount重新定义了基类继承的方法,如SpecialAccount中的withdraw函数,当调用s:withdraw(200)时,Lua就不会再Account中查找了,因为Lua会在SpecialAccount中找到withdraw方法。

     

    补充说明:

          Lua中对象有一个特殊现象,无需为指定一种新行为而创建一个新类,如果只有一个对象需要这种特殊的行为,那么可以直接在该对象中实现这个行为,例如,账户s表示一个特殊的客户,这个客户的透支额度总是余额的10%。那么可以这么修改这个对象:

     clipboard[4]

    在这段代码后,调用s:withdraw(200)还是会执行SpecialAccount中的withdraw函数,但是withdraw调用的self:getLimit则是上面的定义。

     

    完整代码:

    模块结构:

    image

    init.lua 

    MAccount=require("class.account")
    MSpecialAccount=require("class.specialAccount")
    local LoggerConsole=require("logging.console")
    Logger=LoggerConsole()



    main.lua   

    local path="C:\Users\Administrator\Desktop 2\Thinking\Lua\"
    package.path=string.format("%s;%s?.lua;%s?/init.lua",package.path,path,path)
    
    require("class")
    
    local function main()
        local account=MAccount.Account:new()
        account:deposit(500)
        account:withdraw(125)
        print(account)
    
    
        account=MSpecialAccount.SpecialAccount:new()
        print(account:getLimit())
        account:deposit(300)
        account:withdraw(1200)
        print(account)
    end
    
    main()

     

    说明:

            上述修改了package.path 的路径,具体原因参考 本博客“【Lua】模块和包”文章

  • 相关阅读:
    夺冠概率蓝桥杯
    Memcache配置
    [置顶] 6个月:从小白到程序员,也许没你想的那么难
    Delphi Messagebox自动关闭
    最近读园内的几篇好的文章的摘录及感悟
    近期项目的两点教训
    win7网络连接优先顺序设置方法
    WebSerivce学习笔记
    Delphi 控制摄像头操作
    郁闷的一天
  • 原文地址:https://www.cnblogs.com/luosongchao/p/4115783.html
Copyright © 2011-2022 走看看