lua 面向对象实现

虽然lua是一门小巧的胶水语言,但是它也是可以进行面向对象编程的,我们可以实现多继承和单继承,继承都是靠lua的setmetatable实现的。

  • Name = {}
       function Name:new(o) 
        o = o or {}
        setmetatable(o, {__index = self})
        return o
     end
    
     function Name:setName(name)
        self.name = name
     end
    
     function Name:getName()
        return self.Name
    end
    
    -- 在lua中A:b()等价于A.b(self),像标准库中string.len 等价于"xxx":len, 但是为了兼容性更倾向于写作string.len("xxx")
    
  • 单继承

    --定义继承
    SpecName = Name:New({age=25})
    function SpecName:setNewName(name)
          if self.getAge() > 9 then
              self:setName(name)
          else
              error("You must give an age!")
          end
    end
    
    function SpecName:getAge()
           return self.age
    end
    
  • 多继承

    function search(k, plist)
        for i=1,#plist do
             if plist[i][k] ~= nil then return plist[i][k] end
         end
    end
    
    function createClass(...)
        local args = {...}
        local c = {}
        setmetatable(c, {__index = function(self, k) 
            return search(k, args) 
        end})
    
        c.__index = c
        function c:new(o) 
            o = o or {}
            setmetatable(o, c)
            return o
        end
        return c 
    end
    
    Balance = {balance= 10}
    function Balance:new(o) 
        o = o or {}
        setmetatable(o, {__index = self})
        return o
    end
    
    function Balance:despoit(v)
        self.balance = self.balance + v
    end
    
    function Balance:withDraw(v)
        if self.balance < v then
             error("Bad case")
        else
            self.balance = self.balance - v
        end
    end
    
    Name={}
    function Name:new(o) 
         o = o or {}
         setmetatable(o, {__index = self})
         return o
    end
    
    function Name:setName(name)
        self.name = name
    end
    
    function Name:getName()
        return self.name
    end
    
    c = createClass(Balance, Name)
    c:despoit(100)
    c:withDraw(10)
    print(c.balance)  --> 100
    c:setName("wbz")
    print(c:getName()) --> wbz
    
  • 隐藏私有变量

     function newAccount(initBalance)
        local self = {balance=initBalance}
        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