国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Lua面向?qū)ο缶幊痰幕驹硎纠忝靼讕追郑?/h1>

開發(fā) 前端
這篇文章主要描述:在Lua?語言中,如何通過table結(jié)構(gòu)來實(shí)現(xiàn)面向?qū)ο缶幊獭V饕强吹侥厨B教程上錯誤百出,估計示例代碼自己都沒有測試過;關(guān)于Lua?語言中的table?以及metatable的基本知識,這里就不贅述了,官方手冊中描述的很清楚。

一些廢話

Lua語言是一個小而美的語言,使用者不多。

估計閱讀這篇文章的人也不會多,姑且當(dāng)做一篇筆記吧。

這篇文章主要描述:在Lua語言中,如何通過table結(jié)構(gòu)來實(shí)現(xiàn)面向?qū)ο缶幊獭?/p>

主要是看到某鳥教程上錯誤百出,估計示例代碼自己都沒有測試過;

關(guān)于Lua語言中的table以及metatable的基本知識,這里就不贅述了,官方手冊中描述的很清楚。

測試代碼

1 #!/usr/bin/lua
2
3 ------------------------------ class A
4 A = {
5 a = 1,
6 funcA = function()
7 print("this is funcA")
8 end
9 }
10
11 function A:new(t)
12 local t = t or {}
13 self.__index = self
14 setmetatable(t, self)
15 return t
16 end
17
18 function A:myadd(num)
19 self.a = self.a + num
20 end
21
22 objA = A:new()
23 print("objA.a = " .. objA.a)
24 print(objA.funcA())
25 print(string.rep("-", 20))
26
27 ------------------------------ class B
28 B = A:new({
29 b = 2,
30 funcB = function()
31 print("this is funcB")
32 end
33 })
34
35 objB = B:new()
36 print("objB.a = " .. objB.a)
37 print("objB.b = " .. objB.b)
38 print(objB.funcA())
39 print(objB.funcB())
40
41 objB:myadd(10)
42 print("objA.a = " .. objA.a)
43 print("objB.a = " .. objB.a)

執(zhí)行結(jié)果如下:

$ ./oop.lua 
objA.a = 1
this is funcA

--------------------
objB.a = 1
objB.b = 2
this is funcA

this is funcB

objA.a = 1
objB.a = 11

代碼說明

基類(父類) A

首先來分析下4-25行的代碼。

4-9行:定義父類A的成員變量和函數(shù)(按照C++中的習(xí)慣,可以叫做方法),可以看出Lua語言中的函數(shù)是“一等公民”,是可以賦值給一個變量的。

11-16行:相當(dāng)于是構(gòu)造函數(shù),用來創(chuàng)建一個父類A的對象。

18-20行:給父類A增加一個函數(shù),待會在分析子類B的時候再說。

22行:調(diào)用A:new()函數(shù),創(chuàng)建一個類A的對象,賦值給變量objA。

在A:new()函數(shù)中,關(guān)鍵是第13行代碼:此時self等于A,就相當(dāng)于是A.__index = A,這是合法的。

因為函數(shù)的調(diào)用方式是A:new(),Lua的語法糖會把A作為第一個參數(shù)傳遞給new()函數(shù)的第一個隱藏參數(shù)self。

然后執(zhí)行14行的setmetatable(t, self),相當(dāng)于把表t的元表設(shè)置為A。

以上兩行搞明白之后,23-24行的打印語句就簡單了:

23行:因為表objA中沒有成員a,但是objA被設(shè)置了元表A,而且該元表A帶有__index屬性,該屬性的值是表A自己,于是就到A中查找是否有成員a,于是就打印出:

objA.a = 1

__index 屬性的值,可以是一個表,可以是一個函數(shù);

只不過這里特殊一點(diǎn):__index 設(shè)置為 A 自己;

24行:查找函數(shù)的過程是一樣的,找到元表A的__index屬性的值,也就是表A自己中的funcA函數(shù),然后調(diào)用,打印出:

this is funcA

派生類(子類) B

28-33行:定義了子類B,其實(shí)它也是一個對象。

在創(chuàng)建函數(shù)A:new(t)中,參數(shù)t的值是:

local t = {
b = 2,
funcB = function()
print("this is funcB")
end
}

此時,self仍然是父類A,B的創(chuàng)建過程與objA的創(chuàng)建過程是一樣的,只不過給參數(shù)t設(shè)置了子類B自己的成員變量和函數(shù)。

所以,B的元表被設(shè)置為A(14行代碼的功勞),當(dāng)然了A的__index仍然被設(shè)置為A自己。

關(guān)鍵是35行:objB = B:new(),得仔細(xì)嘮嘮。

子類B并沒有自己的new函數(shù),但是類B(也是一個 table) 的元表被設(shè)置為A,并且A.__index = A,所以最終就找到了A中的new函數(shù),也就是11-16行代碼。

進(jìn)入這個函數(shù)中時,第一個隱藏參數(shù)self被設(shè)置為 B 了,因為函數(shù)調(diào)用形式是:B:new()。

所以:

  • 13 行 self.__index = self  相當(dāng)于設(shè)置 B.__index = B
  • 14 行 etmetatable(t, self) 相當(dāng)于把表 t 的元表設(shè)置為 B

new()函數(shù)返回之后,就把t賦值給objB。

下面再看一下36-39行的打印語句:

36 print("objB.a = " .. objB.a)
37 print("objB.b = " .. objB.b)
38 print(objB.funcA())
39 print(objB.funcB())

36行:objB中并沒有成員a,但是objB的元表是B,而且B.__index = B,所以就到B中去查找a。

雖然B中也沒有a,但是B的元表是A,而且A.__index = A,所以就在A中找到了成員a,打印出:

objB.a = 1

37行:objB中并沒有成員b,但是objB的元表是B,而且B.__index = B,所以在B中找到了成員b,因此打印出:

objB.b = 2

37和38行的查找過程是類似的,只不過換成了函數(shù)而已。

子類對象操作自己的變量

41行:objB:myadd(10)。

查找myadd函數(shù)的過程與查找obj.a的過程是一樣的,這里再嘮叨一遍:

  • objB 中并沒有函數(shù) myadd,但是 objB 的元表是 B,而且 B.__index = B,所以就到 B 中去查找 myadd;
  • 雖然 B 中也沒有 myadd,但是 B 的元表是 A,而且 A.__index = A,所以就在 A 中找到了函數(shù) myadd;

于是就調(diào)用了函數(shù):

18 function A:myadd(num)
19 self.a = self.a + num
20 end

而且self等于objB,因此函數(shù)體中就等于是:

objB.a = objB.a + 10

加法表達(dá)式中的objB.a的讀取過程,上面已經(jīng)描述過了,最終定位到的是父類A中的a,即:1。

1 + 10 = 11,然后把11賦值給objB.a。

在賦值操作中,被賦值的objB.a就不再是父類A中的那個a了!

因為objB本質(zhì)是一個table,給objB設(shè)置鍵值對的時候:

  • 如果鍵已經(jīng)存在了,那么就直接設(shè)置該鍵的值;
  • 如果鍵不存在,那么 lua 會看它的元表中是否有 __newindex 字段(可以是一個table,也可以是一個函數(shù));
  • 2-1. 如果有   __newindex 字段,那么就是調(diào)用 __newindex (如果是一個函數(shù)),或者在 __newindex 中添加鍵值對(如果是一個table);
  • 2-2. 如果沒有 __newindex 字段,那么就直接在 objB 中存儲該鍵值對;

根據(jù)上面這個規(guī)則,就會設(shè)置objB.a = 11。

明白以上這些之后,42和43行的打印語句就不復(fù)雜了。

42行:objA最終找到的a是父類A中的成員a,打印出:objA.a = 1。

43行:objB中自己已經(jīng)有了成員a,所以打印出:objB.a = 11。

繼續(xù)往下繼承

有了上面的基礎(chǔ),再從子類B中派生出類C,C派生出類D... 都不是什么問題了,如下所示:

C = B:new()
objC = C:new()
print("objC.a = " .. objC.a)
print("objC.b = " .. objC.b)
print(objC.funcA())
print(objC.funcB())

感興趣的讀者可以自己測試一下。

責(zé)任編輯:武曉燕 來源: IOT物聯(lián)網(wǎng)小鎮(zhèn)
相關(guān)推薦

2024-01-30 09:21:01

deltaFifo機(jī)制apiServer

2019-11-28 10:45:28

ZooKeeper源碼分布式

2012-01-12 14:37:34

jQuery

2010-01-07 09:53:09

Winform多線程編

2013-04-07 14:09:55

Android應(yīng)用基本

2020-03-21 14:57:14

手機(jī)定位智能手機(jī)APP

2010-08-20 13:29:33

OFDM

2009-02-24 09:43:00

IP電話原理

2011-11-29 12:17:00

2010-09-08 15:25:15

Linux系統(tǒng)分區(qū)

2011-08-10 19:33:09

Cocoa對象

2010-03-17 13:35:02

2016-08-18 00:04:09

網(wǎng)絡(luò)爬蟲抓取系統(tǒng)服務(wù)器

2016-08-17 23:53:29

網(wǎng)絡(luò)爬蟲抓取系統(tǒng)

2021-02-08 21:40:04

SockmapBPF存儲

2011-07-07 14:22:27

Cocoa 對象 生命周期

2010-06-18 17:28:37

Linux Anacr

2013-01-09 09:27:09

面向?qū)ο?/a>計算機(jī)編程

2020-11-26 13:54:03

容器LinuxDocker

2009-06-11 09:56:09

MySQL Repli原理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

2018中文字幕一区二区三区| 国产91色在线|亚洲| 91精品久久久久久久久久久久久| 国产av人人夜夜澡人人爽| 你懂得影院夜精品a| 成人在线app| 欧美日本不卡高清| 欧美一区二区| 91精品综合久久久久久| 精选一区二区三区四区五区| aaa在线观看| 国产在线不卡| 884aa四虎影成人精品一区| jizz欧美大全| 九九综合在线| 亚洲午夜羞羞片| 91欧美激情另类亚洲| 欧美一级在线亚洲天堂| 亚洲女同另类| 国产亚洲综合性久久久影院| 国内精品久久久久| 小草在线视频在线免费视频| 国产精品久久久久蜜臀| 欧美一区二区大片| 国产中文字幕乱人伦在线观看| 奇米777日韩| 日本一区二区三区视频视频| 国产精品一二区| aaa大片在线观看| 99re免费视频精品全部| 国产精品成人国产乱一区 | 牛牛电影国产一区二区| 国产精品综合二区| 国产综合在线视频| 一区二区三区日本久久久| 欧美视频一区在线| 妞干网在线视频观看| 久久资源中文字幕| 亚洲国产日韩一区| 182午夜在线观看| 一本综合精品| 欧美黑人性猛交| 免费在线视频欧美| 91浏览器在线视频| 国产成人免费电影| 日韩不卡手机在线v区| 久久99精品国产99久久6尤物| 日韩一区av| 久久综合综合久久综合| 18一19gay欧美视频网站| av网站在线免费播放| 日韩三级高清在线| 美女免费免费看网站| 人人爽香蕉精品| 国产精品免费一区豆花| av亚洲一区二区三区| 欧美国产乱视频| 亚洲天天影视网| 一本一道久久a久久综合精品| 日韩大片在线播放| 中文字幕精品视频| 91精品大全| 亚洲第一区第一页| 中文字幕免费在线视频| 国产精品中文字幕欧美| 日韩中文字幕组| 精品免费在线视频| 国内精品一区二区三区| 免费精品一区| 精品国产一区二区三区av性色 | 男人操女人逼免费视频| 超碰cao国产精品一区二区| 欧美日韩在线免费视频| 国产区二区三区| 韩日欧美一区二区三区| 91精品国产高清久久久久久91裸体 | 欧美视频日韩| 成人在线观看毛片| 久久精品观看| 96sao精品视频在线观看| 一本色道69色精品综合久久| 欧美videos大乳护士334| 深夜福利在线视频| 亚洲午夜久久久久久久| 最新国产露脸在线观看| 综合色婷婷一区二区亚洲欧美国产| 91精品久久久| 欧美性受xxx| 亚洲精品黄色| 国产精品不卡在线观看| 日本三级中国三级99人妇网站| 国产福利电影在线播放| 欧美香蕉大胸在线视频观看 | 国产欧美日韩在线一区二区| 日韩在线欧美在线国产在线| 三级在线看中文字幕完整版| 欧美性猛交xxxx乱大交退制版| 欧亚一区二区| 国产厕所精品在线观看| 亚洲综合男人的天堂| 久久久久久久久影视| 亚洲欧洲99久久| 精品人妻大屁股白浆无码| 99久久999| 亚洲九九九在线观看| 五月婷婷六月丁香激情| 欧美日韩电影在线| 日本a√在线观看| 精品一区二区成人精品| 亚洲综合在线一区| 国产成人综合亚洲91猫咪| 日韩在线中文字幕| 亚洲免费高清视频在线| 精品欧美一区二区精品久久| 国产精品久久久久77777丨| 色综合天天综合网国产成人综合天| 欧美成人精品在线观看| 免费在线观看日韩视频| 欧美三级黄网| 久久久国产精品亚洲一区| 川上优av中文字幕一区二区| 欧美人与动牲交xxxxbbbb| 欧美一区二区在线播放| 欧美wwwwwww| 蜜臀久久99精品久久久久久宅男| 蜜臀av一区二区在线免费观看 | 久久精品无码一区二区日韩av| 日韩成人xxxx| 欧美bbbxxxxx| 好吊妞www.84com只有这里才有精品| 亚洲一区欧美一区| 无码日韩精品一区二区免费| 成久久久网站| 91国产在线精品| 99视频国产精品| 激情丁香在线| 91麻豆精品久久久久蜜臀| 日韩大片在线| 三级毛片在线免费看| 成人国产精品久久久| 欧美日韩中文字幕在线| 一本色道久久综合亚洲精品婷婷| 日韩一区二区三区视频在线观看 | 国产高清精品在线| 欧美精品高清| 国模吧无码一区二区三区 | 国产精品视频你懂的| 丝袜足控免费网站xx网站| 欧美日韩国产首页| 久久av最新网址| 2001个疯子在线观看| 欧美高清第一页| 国产精品久久久久久久午夜片 | 日韩精品视频在线播放| 亚洲十八**毛片| 欧美亚洲伦理www| 亚洲国产一区二区三区青草影视| 日韩伦理一区| 成人在线免费电影| 中文字幕久热精品在线视频 | 电影亚洲一区| 日产日韩在线亚洲欧美| 国产欧美日本| koreanbj精品视频一区| 欧美日韩国产在线看| 狠狠88综合久久久久综合网| av网站在线看| 欧美三级在线观看视频| 欧美最近摘花xxxx摘花| 久久99精品久久久| 中文字幕免费在线视频| 国产区一区二区| 中文一区一区三区高中清不卡| 一区二区高清不卡| 久久艹在线视频| 尤物精品在线| 成人午夜激情av| 国产拍精品一二三| 97se亚洲国产综合自在线观| 久久人人爽人人爽人人片av不| 久久久久久亚洲精品不卡4k岛国| 99久久久无码国产精品6| 成人77777| 国产不卡在线| 日韩电影免费观| 男女激情无遮挡| 久久久久免费视频| 欧美影院一区二区| 国产成人免费xxxxxxxx| 啄木系列成人av电影| 97影院秋霞午夜在线观看| 成年人在线看片| 黄色精品一区二区| 一区二区三区无毛| 可以在线观看的av| 久久精品国产亚洲aⅴ| 国产麻豆一区二区三区| 一区二区三区欧美成人| 欧美一级免费视频| 亚洲免费视频网站|