青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

每天早晨叫醒你的不是鬧鐘,而是夢想

  C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
  62 Posts :: 0 Stories :: 5 Comments :: 0 Trackbacks

常用鏈接

留言簿(1)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

Lua中的table就是一種對象,但是如果直接使用仍然會存在大量的問題,見如下代碼:

1 Account = {balance = 0}
2 function Account.withdraw(v)
3 Account.balance = Account.balance - v
4 end
5 --下面是測試調用函數
6 Account.withdraw(100.00)

    在上面的withdraw函數內部依賴了全局變量Account,一旦該變量發生改變,將會導致withdraw不再能正常的工作,如:

1 a = Account; Account = nil
2 a.withdraw(100.00) --將會導致訪問空nil的錯誤。

    這種行為明顯的違反了面向對象封裝性和實例獨立性。要解決這一問題,我們需要給withdraw函數在添加一個參數self,他等價于Java/C++中的this,見如下修改:

1 function Account.withdraw(self,v)
2 self.balance = self.balance - v
3 end
4 --下面是基于修改后代碼的調用:
5 a1 = Account; Account = nil
6 a1.withdraw(a1,100.00) --正常工作。

    針對上述問題,Lua提供了一種更為便利的語法,即將點(.)替換為冒號(:),這樣可以在定義和調用時均隱藏self參數,如:

1 function Account:withdraw(v)
2 self.balance = self.balance - v
3 end
4 --調用代碼可改為:
5 a:withdraw(100.00)


    1. 類:
    Lua在語言上并沒有提供面向對象的支持,因此想實現該功能,我們只能通過table來模擬,見如下代碼及關鍵性注釋:

復制代碼
 1 --[[
2 在這段代碼中,我們可以將Account視為class的聲明,如Java中的:
3 public class Account
4 {
5 public float balance = 0;
6 public Account(Account o);
7 public void deposite(float f);
8 }
9 --]]
10 --這里balance是一個公有的成員變量。
11 Account = {balance = 0}
12
13 --new可以視為構造函數
14 function Account:new(o)
15 o = o or {} --如果參數中沒有提供table,則創建一個空的。
16 --將新對象實例的metatable指向Account表(類),這樣就可以將其視為模板了。
17 setmetatable(o,self)
18 --在將Account的__index字段指向自己,以便新對象在訪問Account的函數和字段時,可被直接重定向。
19 self.__index = self
20 --最后返回構造后的對象實例
21 return o
22 end
23
24 --deposite被視為Account類的公有成員函數
25 function Account:deposit(v)
26 --這里的self表示對象實例本身
27 self.balance = self.balance + v
28 end
29
30 --下面的代碼創建兩個Account的對象實例
31
32 --通過Account的new方法構造基于該類的示例對象。
33 a = Account:new()
34 --[[
35 這里需要具體解釋一下,此時由于table a中并沒有deposite字段,因此需要重定向到Account,
36 同時調用Account的deposite方法。在Account.deposite方法中,由于self(a對象)并沒有balance
37 字段,因此在執行self.balance + v時,也需要重定向訪問Account中的balance字段,其缺省值為0。
38 在得到計算結果后,再將該結果直接賦值給a.balance。此后a對象就擁有了自己的balance字段和值。
39 下次再調用該方法,balance字段的值將完全來自于a對象,而無需在重定向到Account了。
40 --]]
41 a:deposit(100.00)
42 print(a.balance) --輸出100
43
44 b = Account:new()
45 b:deposit(200.00)
46 print(b.balance) --輸出200
復制代碼


    2. 繼承:
    繼承也是面向對象中一個非常重要的概念,在Lua中我們仍然可以像模擬類那樣來進一步實現面向對象中的繼承機制,見如下代碼及關鍵性注釋:

復制代碼
 1 --需要說明的是,這段代碼僅提供和繼承相關的注釋,和類相關的注釋在上面的代碼中已經給出。
2 Account = {balance = 0}
3
4 function Account:new(o)
5 o = o or {}
6 setmetatable(o,self)
7 self.__index = self
8 return o
9 end
10
11 function Account:deposit(v)
12 self.balance = self.balance + v
13 end
14
15 function Account:withdraw(v)
16 if v > self.balance then
17 error("Insufficient funds")
18 end
19 self.balance = self.balance - v
20 end
21
22 --下面將派生出一個Account的子類,以使客戶可以實現透支的功能。
23 SpecialAccount = Account:new() --此時SpecialAccount仍然為Account的一個對象實例
24
25 --派生類SpecialAccount擴展出的方法。
26 --下面這些SpecialAccount中的方法代碼(getLimit/withdraw),一定要位于SpecialAccount被Account構造之后。
27 function SpecialAccount:getLimit()
28 --此時的self將為對象實例。
29 return self.limit or 0
30 end
31
32 --SpecialAccount將為Account的子類,下面的方法withdraw可以視為SpecialAccount
33 --重寫的Account中的withdraw方法,以實現自定義的功能。
34 function SpecialAccount:withdraw(v)
35 --此時的self將為對象實例。
36 if v - self.balance >= self:getLimit() then
37 error("Insufficient funds")
38 end
39 self.balance = self.balance - v
40 end
41
42 --在執行下面的new方法時,table s的元表已經是SpecialAccount了,而不再是Account。
43 s = SpecialAccount:new{limit = 1000.00}
44 --在調用下面的deposit方法時,由于table s和SpecialAccount均未提供該方法,因此訪問的仍然是
45 --Account的deposit方法。
46 s:deposit(100)
47
48
49 --此時的withdraw方法將不再是Account中的withdraw方法,而是SpecialAccount中的該方法。
50 --這是因為Lua先在SpecialAccount(即s的元表)中找到了該方法。
51 s:withdraw(200.00)
52 print(s.balance) --輸出-100
復制代碼


    3. 私密性:
    私密性對于面向對象語言來說是不可或缺的,否則將直接破壞對象的封裝性。Lua作為一種面向過程的腳本語言,更是沒有提供這樣的功能,然而和模擬支持類與繼承一樣,我們仍然可以在Lua中通過特殊的編程技巧來實現它,這里我們應用的是Lua中的閉包函數。該實現方式和前面兩個示例中基于元表的方式有著很大的區別,見如下代碼示例和關鍵性注釋:

復制代碼
 1 --這里我們需要一個閉包函數作為類的創建工廠
2 function newAccount(initialBalance)
3 --這里的self僅僅是一個普通的局部變量,其含義完全不同于前面示例中的self。
4 --這里之所以使用self作為局部變量名,也是為了方便今后的移植。比如,以后
5 --如果改為上面的實現方式,這里應用了self就可以降低修改的工作量了。
6 local self = {balance = initialBalance} --這里我們可以將self視為私有成員變量
7 local withdraw = function(v) self.balance = self.balance - v end
8 local deposit = function(v) self.balance = self.balance + v end
9 local getBalance = function() return self.balance end
10 --返回對象中包含的字段僅僅為公有方法。事實上,我們通過該種方式,不僅可以實現
11 --成員變量的私有性,也可以實現方法的私有性,如:
12 --local privateFunction = function() --do something end
13 --只要我們不在輸出對象中包含該方法的字段即可。
14 return {withdraw = withdraw, deposit = deposit, getBalance = getBalance}
15 end
16
17 --和前面兩個示例不同的是,在調用對象方法時,不再需要self變量,因此我們可以直接使用點(.),
18 --而不再需要使用冒號(:)操作符了。
19 accl = newAccount(100.00)
20 --在函數newAccount返回之后,該函數內的“非局部變量”表self就不再能被外部訪問了,只能通過
21 --該函數返回的對象的方法來操作它們。
22 accl.withdraw(40.00)
23 print(acc1.getBalance())
復制代碼

    事實上,上面的代碼只是給出一個簡單的示例,在實際應用中,我們可以將更多的私有變量存放于上例的局部self表中。

posted on 2014-02-17 17:41 沛沛 閱讀(295) 評論(0)  編輯 收藏 引用 所屬分類: Script
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲一区视频在线| 欧美黄色免费| 国产精品亚洲综合一区在线观看| 午夜欧美大尺度福利影院在线看| 亚洲第一成人在线| 国产区欧美区日韩区| 欧美日韩国产首页在线观看| 国产精品专区第二| 久久国产主播| 欧美一区深夜视频| 亚洲欧美三级在线| 翔田千里一区二区| 一区二区三区国产盗摄| 欧美在线观看视频一区二区三区 | 91久久中文字幕| 女女同性精品视频| 久久女同互慰一区二区三区| 蜜桃精品久久久久久久免费影院| 久久久久久有精品国产| 91久久线看在观草草青青| 亚洲精品一二区| 日韩午夜激情| 亚洲宅男天堂在线观看无病毒| 久久久精品五月天| 欧美va天堂在线| 欧美日韩性视频在线| 国产精品久久久久影院色老大 | 国产一区二区三区成人欧美日韩在线观看| 一色屋精品视频在线看| 亚洲欧洲日产国码二区| 在线视频一区观看| 久久精品国产久精国产思思| 亚洲人成在线观看一区二区 | 亚洲精品影视| 午夜精品久久久久久久久久久久| 久久gogo国模啪啪人体图| 小嫩嫩精品导航| 亚洲国产你懂的| 一本一本a久久| 久久精品视频免费观看| 欧美日韩一级视频| 亚洲乱码国产乱码精品精可以看 | 亚洲精品视频在线观看网站| 亚洲国产天堂久久综合| 欧美中文字幕久久| 欧美精品尤物在线| 国产视频一区三区| 亚洲精品国久久99热| 99re6这里只有精品| 欧美福利电影网| 欧美 日韩 国产在线| 国产精品高潮粉嫩av| 欧美日韩中文字幕在线| 亚洲夫妻自拍| 校园春色国产精品| 91久久在线视频| 欧美在线亚洲一区| 欧美日韩三级电影在线| 久久久精品性| 国产精品入口麻豆原神| 亚洲精品免费一二三区| 日韩一级在线| 欧美国产极速在线| 久久成人免费网| 国产日韩久久| 亚洲男女自偷自拍| 亚洲人成人一区二区在线观看| 欧美在线观看www| 国产精品入口麻豆原神| 久久精品亚洲一区| 午夜久久黄色| 国产精品美女久久| 欧美一级片一区| 禁久久精品乱码| 午夜亚洲福利在线老司机| 日韩一级精品视频在线观看| 欧美日韩国产区一| 亚洲综合色网站| 午夜在线视频观看日韩17c| 国产亚洲精品激情久久| 久久久精品动漫| 蜜桃久久精品乱码一区二区| 亚洲另类一区二区| 亚洲一区二区三区精品在线| 国产综合久久久久久鬼色| 欧美韩国在线| 国产精品久久久久久久久久免费看 | 国产欧美日韩精品专区| 久久一区二区三区四区| 米奇777超碰欧美日韩亚洲| 亚洲性感激情| 久久久久久自在自线| 在线亚洲精品福利网址导航| 亚洲女同同性videoxma| 亚洲国产精品精华液网站| 亚洲午夜视频在线| 亚洲欧洲一区二区天堂久久| 亚洲影院免费观看| 亚洲黄色在线| 欧美一区二区三区免费看| 9色精品在线| 久久九九免费| 午夜精品一区二区三区电影天堂| 国产亚洲精品aa午夜观看| 国产专区一区| av成人毛片| 影视先锋久久| 亚洲午夜在线观看| 99re66热这里只有精品3直播| 欧美一区久久| 亚洲男女毛片无遮挡| 欧美精品九九| 久热精品在线| 国产精品夜色7777狼人| 最近中文字幕mv在线一区二区三区四区| 国产女主播视频一区二区| 亚洲精品视频中文字幕| 亚洲国产日韩在线一区模特| 欧美一区二区| 欧美一区二区播放| 国产精品国产精品| 一本到12不卡视频在线dvd| 夜夜嗨av一区二区三区网站四季av | 久久五月天婷婷| 久久精品欧洲| 国产日本欧美一区二区三区在线 | 亚洲第一在线视频| 午夜一区二区三区在线观看| 亚洲社区在线观看| 欧美波霸影院| 亚洲高清二区| 亚洲电影av| 久久噜噜噜精品国产亚洲综合| 亚洲一区二区三区高清不卡| 欧美日韩国产经典色站一区二区三区| 欧美高清视频| 亚洲片在线资源| 美女视频一区免费观看| 欧美成在线观看| 亚洲国产精品成人综合| 老牛嫩草一区二区三区日本| 欧美aa在线视频| 亚洲人成网站999久久久综合| 嫩草影视亚洲| 91久久国产综合久久蜜月精品| 91久久综合亚洲鲁鲁五月天| 欧美国产国产综合| 亚洲日韩成人| 亚洲在线国产日韩欧美| 国产精品久久久久9999高清| 亚洲女人小视频在线观看| 久久噜噜噜精品国产亚洲综合| 在线看无码的免费网站| 久久亚裔精品欧美| 亚洲日本成人在线观看| 亚洲伊人伊色伊影伊综合网| 国产精品一区视频| 久久综合伊人77777| 亚洲伦理在线观看| 久久成人免费| 亚洲区一区二| 欧美色中文字幕| 欧美一级播放| 亚洲精品视频在线观看网站| 久久国产精品色婷婷| 亚洲欧洲日韩在线| 先锋影音一区二区三区| 欧美肥婆在线| a91a精品视频在线观看| 欧美综合国产| 亚洲黄色有码视频| 国产精品毛片a∨一区二区三区| 久久精品理论片| 亚洲国产精品尤物yw在线观看 | 欧美日韩在线直播| 亚洲欧美电影在线观看| 欧美成人第一页| 亚洲一区激情| 在线看成人片| 国产精品私拍pans大尺度在线 | 亚洲一区精品视频| 欧美激情第8页| 欧美在线免费观看| 日韩一级不卡| 有码中文亚洲精品| 国产日韩欧美精品在线| 欧美日韩福利视频| 另类激情亚洲| 欧美在线播放视频| 亚洲一区在线视频| 亚洲另类自拍| 欧美激情一区二区久久久| 久久亚洲精品欧美| 久久久久久久久一区二区| 亚洲无限乱码一二三四麻| 亚洲高清色综合| 国产亚洲一区二区三区在线观看 | 免费日韩av| 久久黄色级2电影| 午夜久久久久久|