<noframes id="bblxs"><output id="bblxs"><output id="bblxs"></output></output><dd id="bblxs"><font id="bblxs"><output id="bblxs"></output></font></dd>
<dd id="bblxs"></dd><font id="bblxs"></font>
<dd id="bblxs"></dd><font id="bblxs"></font><dd id="bblxs"></dd>
<output id="bblxs"><output id="bblxs"><dd id="bblxs"></dd></output></output>
<dd id="bblxs"></dd>
<dd id="bblxs"><output id="bblxs"><output id="bblxs"></output></output></dd><font id="bblxs"></font><font id="bblxs"><font id="bblxs"><output id="bblxs"></output></font></font><dd id="bblxs"></dd><dd id="bblxs"><font id="bblxs"><tr id="bblxs"></tr></font></dd><font id="bblxs"></font>
<dd id="bblxs"></dd>
<dd id="bblxs"><output id="bblxs"></output></dd><dd id="bblxs"><font id="bblxs"></font></dd>
<dd id="bblxs"></dd><font id="bblxs"><output id="bblxs"><tr id="bblxs"></tr></output></font><font id="bblxs"></font>
<font id="bblxs"><output id="bblxs"><noframes id="bblxs"><dd id="bblxs"><output id="bblxs"></output></dd><font id="bblxs"></font><dd id="bblxs"><output id="bblxs"><tr id="bblxs"></tr></output></dd><font id="bblxs"></font><dd id="bblxs"></dd> <dd id="bblxs"></dd><noframes id="bblxs"><font id="bblxs"></font><font id="bblxs"></font>
<font id="bblxs"></font>
<dd id="bblxs"><font id="bblxs"><tr id="bblxs"></tr></font></dd><font id="bblxs"><output id="bblxs"><tr id="bblxs"></tr></output></font>
<font id="bblxs"></font>
<dd id="bblxs"></dd>
<dd id="bblxs"></dd>
<dd id="bblxs"><output id="bblxs"></output></dd><dd id="bblxs"></dd>
您現在的位置: 通信界 >> 接入系統 >> 技術正文  
 
Lua面向對象編程的基本原理示例
[ 通信界 / 道哥 / www.findmyhalf.com / 2022/10/30 18:42:03 ]
 

目錄

· 一些廢話

· 測試代碼

· 代碼說明

· 基類(父類) A

· 派生類(子類) B

· 子類對象操作私有變量

· 繼續往下繼承

別人的經驗,我們的階梯!

一些廢話

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

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

這篇文章主要描述:在Lua語言中,如何通過table結構來實現面向對象編程。

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

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

測試代碼 

image.png

image.png

執行結果如下:

image.png

代碼說明 

基類(父類) A

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

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

11-16行:相當于是構造函數,用來創建一個父類A的對象。

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

22行:調用A:new()函數,創建一個類A的對象,賦值給變量objA。

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

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

然后執行14行的setmetatable(t, self),相當于把表t的元表設置為A。

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

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

image.png

__index 屬性的值,可以是一個表,可以是一個函數;

只不過這里特殊一點:__index 設置為 A 自己;

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

image.png

派生類(子類) B

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

在創建函數A:new(t)中,參數t的值是:

image.png

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

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

關鍵是35行:objB = B:new(),得仔細嘮嘮。

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

進入這個函數中時,第一個隱藏參數self被設置為 B 了,因為函數調用形式是:B:new()。

所以:

13 行 self.__index = self  相當于設置 B.__index = B

14 行 etmetatable(t, self) 相當于把表 t 的元表設置為 B

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

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

image.png

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

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

image.png

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

image.png

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

子類對象操作自己的變量

41行:objB:myadd(10)。

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

1. objB 中并沒有函數 myadd,但是 objB 的元表是 B,而且 B.__index = B,所以就到 B 中去查找 myadd;

2. 雖然 B 中也沒有 myadd,但是 B 的元表是 A,而且 A.__index = A,所以就在 A 中找到了函數 myadd;

于是就調用了函數:

image.png

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

image.png

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

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

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

因為objB本質是一個table,給objB設置鍵值對的時候:

1. 如果鍵已經存在了,那么就直接設置該鍵的值;

2. 如果鍵不存在,那么 lua 會看它的元表中是否有 __newindex 字段(可以是一個table,也可以是一個函數);

2-1. 如果有   __newindex 字段,那么就是調用 __newindex (如果是一個函數),或者在 __newindex 中添加鍵值對(如果是一個table);

2-2. 如果沒有 __newindex 字段,那么就直接在 objB 中存儲該鍵值對;

根據上面這個規則,就會設置objB.a = 11。

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

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

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

繼續往下繼承

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

image.png

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

 

作者:道哥 合作媒體:通信界 編輯:顧北

 

 

 
 熱點技術
普通技術 Lua面向對象編程的基本原理示例
普通技術 Arm Neoverse路線圖再添新!為全球計算基礎設施奠定新的起點
普通技術 世界越來越熱,數據中心可不能跟著升溫
普通技術 用戶帶寬增長驅動核心路由器演進
普通技術 賦能下一代5G平臺
普通技術 航天新通QSite,助力5G新基建
普通技術 5G+4G無線網絡協同及組網關鍵技術探討
普通技術 面向5G前傳的半有源WDM技術創新
普通技術 亞馬遜云計算迎來史上最低增速 營收利潤未達華爾街預期
普通技術 華為王金平:擴大體驗紅利格局,引領體驗經營時代
普通技術 兔寶寶質量新突破,“康耐板”解決生態板行業難題
普通技術 無源物聯網如何大規模應用?飛英思特“環境取能”技術成破局關鍵
普通技術 基于傳感器的氣象環境網格監測系統有效改善環境問題
普通技術 【技術分享】持續升級的TWS方案
普通技術 超聲波觸控技術:可穿戴設備和大型顯示屏市場的新爆點
普通技術 5G中的DPD技術,怎么玩?
普通技術 ModbusTCP協議報文詳細分析
普通技術 5G NR中的HARQ機制基本原理
普通技術 Massive MIMO技術應用場景
普通技術 工業自動化發展經歷了哪幾個階段?
  版權與免責聲明: ① 凡本網注明“合作媒體:通信界”的所有作品,版權均屬于通信界,未經本網授權不得轉載、摘編或利用其它方式使用。已經本網授權使用作品的,應在授權范圍內使用,并注明“來源:通信界”。違反上述聲明者,本網將追究其相關法律責任。 ② 凡本網注明“合作媒體:XXX(非通信界)”的作品,均轉載自其它媒體,轉載目的在于傳遞更多信息,并不代表本網贊同其觀點和對其真實性負責。 ③ 如因作品內容、版權和其它問題需要同本網聯系的,請在一月內進行。
通信視界
韋樂平:網絡深度轉型最明確的方向首先就是云
愛立信中國區總裁方迎:將在中國市場重點做好
普通對話 NVIDIA發力數字孿生:站在虛擬和現實之間
普通對話 韋樂平:網絡深度轉型最明確的方向首先就是云
普通對話 中國工程院院士鄔賀銓:6G標準面臨小圈子風險
普通對話 華為丁耘:綠色ICT,共創新價值
普通對話 愛立信中國區總裁方迎:將在中國市場重點做好
普通對話 中國聯通買彥州:廣電5G商用對行業競爭格局不
普通對話 中國聯通陳忠岳:從“提速降費”向“提速提質
普通對話 華為胡厚崑:5G+工業互聯網 數據驅動是關鍵
普通對話 華為郭平:每個人磨好自己的豆腐,就會有一個
普通對話 中國移動楊杰:加快推進新型平臺用工模式規范
普通對話 中國移動簡勤:5G引領數字化轉型 終端承載應用
普通對話 專訪GSMA劉鴻:5G專網誰來建?運營商是最佳選
普通對話 華為甘斌:預計2021年5G用戶將超5億
普通對話 郄勇志:小米被美拉黑事件啟示:實現科技自立
普通對話 聞庫:要有打造“數字中國 光網底座”的使命感
通信前瞻
中國移動李慧鏑:強化數智基建驅動 推進產業轉
蘇少林:打造北京數字經濟“五強”,助力標桿
普通對話 多管齊下,VMware跨云服務助力企業云轉型
普通對話 中國移動李慧鏑:強化數智基建驅動 推進產業轉
普通對話 蘇少林:打造北京數字經濟“五強”,助力標桿
普通對話 中國科大在高安全量子密鑰分發網絡方面取得新
普通對話 華為楊超斌:邁向5.5G持續創新,開啟5G產業新
普通對話 中國聯通買彥州:加強創新力度,協同推進6G技
普通對話 信通院總工敖立:5G工業模組是產業鏈特別短板
普通對話 中興通訊首席發展官崔麗:澎湃“數”動能,助
普通對話 中國移動趙大春:力推北斗與5G產業深度融合
普通對話 信通院徐菲:爭取2021年實現端到端網絡切片自
普通對話 楊澤民:光網絡發展挑戰與機遇并存
普通對話 張杰:“雙千兆”發展面臨四大核心挑戰
普通對話 中國移動董事長楊杰:共創信息服務新生態 共拓
普通對話 王志勤:“5G+工業互聯網”產業發展初期仍面臨
普通對話 中國電信董事長柯瑞文:5G+云網,助力VR產業發
亚洲中文字幕色大焦视频_野狼av午夜福利在线_激情开心_俺也去噜噜噜噜色
<noframes id="bblxs"><output id="bblxs"><output id="bblxs"></output></output><dd id="bblxs"><font id="bblxs"><output id="bblxs"></output></font></dd>
<dd id="bblxs"></dd><font id="bblxs"></font>
<dd id="bblxs"></dd><font id="bblxs"></font><dd id="bblxs"></dd>
<output id="bblxs"><output id="bblxs"><dd id="bblxs"></dd></output></output>
<dd id="bblxs"></dd>
<dd id="bblxs"><output id="bblxs"><output id="bblxs"></output></output></dd><font id="bblxs"></font><font id="bblxs"><font id="bblxs"><output id="bblxs"></output></font></font><dd id="bblxs"></dd><dd id="bblxs"><font id="bblxs"><tr id="bblxs"></tr></font></dd><font id="bblxs"></font>
<dd id="bblxs"></dd>
<dd id="bblxs"><output id="bblxs"></output></dd><dd id="bblxs"><font id="bblxs"></font></dd>
<dd id="bblxs"></dd><font id="bblxs"><output id="bblxs"><tr id="bblxs"></tr></output></font><font id="bblxs"></font>
<font id="bblxs"><output id="bblxs"><noframes id="bblxs"><dd id="bblxs"><output id="bblxs"></output></dd><font id="bblxs"></font><dd id="bblxs"><output id="bblxs"><tr id="bblxs"></tr></output></dd><font id="bblxs"></font><dd id="bblxs"></dd> <dd id="bblxs"></dd><noframes id="bblxs"><font id="bblxs"></font><font id="bblxs"></font>
<font id="bblxs"></font>
<dd id="bblxs"><font id="bblxs"><tr id="bblxs"></tr></font></dd><font id="bblxs"><output id="bblxs"><tr id="bblxs"></tr></output></font>
<font id="bblxs"></font>
<dd id="bblxs"></dd>
<dd id="bblxs"></dd>
<dd id="bblxs"><output id="bblxs"></output></dd><dd id="bblxs"></dd>