<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # Lua面向對象編程 #### 類 在 Lua 中,我們可以使用表和函數實現面向對象。將函數和相關的數據放置于同一個表中就形成了一個對象。 ~~~ Account = {balance = 0} function Account:deposit (v) --注意,此處使用冒號,可以免寫self關鍵字;如果使用.號,第一個參數必須是self self.balance = self.balance + v end function Account:withdraw (v) --注意,此處使用冒號,可以免寫self關鍵字; if self.balance > v then self.balance = self.balance - v else error("insufficient funds") end end function Account:new (o) --注意,此處使用冒號,可以免寫self關鍵字; o = o or {} -- create object if user does not provide one setmetatable(o, {__index = self}) return o end a = Account:new() a:deposit(100) b = Account:new() b:deposit(50) print(a.balance) -->100 print(b.balance) -->50 --本來筆者開始是自己寫的例子,但發現的確不如lua作者給的例子經典,所以還是沿用作者的代碼。 ~~~ 上面這段代碼"setmetatable(o, {__index = self})"這句話值得注意。根據我們在元表這一章學到的知識,我們明白,setmetatable將Account作為新建'o'表的原型,所以當o在自己的表內找不到'balance'、'withdraw'這些方法和變量的時候,便會到__index所指定的Account類型中去尋找。 #### 繼承 繼承可以用元表實現,它提供了在父類中查找存在的方法和變量的機制。 ~~~ --定義繼承 --定義繼承 SpecialAccount = Account:new({limit = 1000}) --開啟一個特殊賬戶類型,這個類型的賬戶可以取款超過余額限制1000元 function SpecialAccount:withdraw (v) if v - self.balance >= self:getLimit() then error("insufficient funds") end self.balance = self.balance - v end function SpecialAccount:getLimit () return self.limit or 0 end spacc = SpecialAccount:new() spacc:withdraw(100) print(spacc.balance) --> -100 acc = Account:new() acc:withdraw(100) --> 超出賬戶余額限制,拋出一個錯誤 ~~~ #### 多重繼承 多重繼承肯定不能采用我們在單繼承中的所使用的方法,因為直接采用setmetatable的方式,會造成metatable的覆蓋。在多重繼承中,我們自己利用'__index'元方法定義恰當的訪問行為。 ~~~ local function search (k, plist) for i=1, table.getn(plist) do local v = plist[i][k] -- try 'i'-th superclass if v then return v end end end function createClass (...) local c = {} -- new class -- class will search for each method in the list of its -- parents (`args' is the list of parents) args = {...} setmetatable(c, {__index = function (self, k) return search(k, args) end}) -- prepare `c' to be the metatable of its instances c.__index = c -- define a new constructor for this new class function c:new (o) o = o or {} setmetatable(o, c) return o end -- return new class return c end ~~~ 解釋一下上面的代碼。我們定義了一個通用的創建多重繼承類的函數'createClass',這個函數可以接受多個類。如何讓我們新建的多重繼承類恰當地訪問從不同類中繼承來的函數或者成員變量呢?我們就用到了'search'函數,該函數接受兩個參數,第一個參數是想要訪問的類成員的名字,第二個參數是被繼承的類列表。通過一個for循環在列表的各個類中尋找想要訪問成員。 我們再定一個新類,來驗證'createClass'的正確性。 ~~~ Named = {} function Named:getname () return self.name end function Named:setname (n) self.name = n end NamedAccount = createClass(Account, Named) --同時繼承Account 和 Named兩個類 account = NamedAccount:new{name = "Paul"} --使用這個多重繼承類定義一個實例 print(account:getname()) --> Pauls account:deposit(100) print(account.balance) --> 100 ~~~ #### 成員私有性 在面向對象當中,如何將成員內部實現細節對使用者隱藏,也是值得關注的一點。在 Lua 中,成員的私有性,使用類似于函數閉包的形式來實現。在我們之前的銀行賬戶的例子中,我們使用一個工廠方法來創建新的賬戶實例,通過工廠方法對外提供的閉包來暴露對外接口。而不想暴露在外的例如balace成員變量,則被很好的隱藏起來。 ~~~ function newAccount (initialBalance) 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 a = newAccount(100) a.deposit(100) print(a.getBalance()) --> 200 print(a.balance) --> nil ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看