Lua學習(二)物件導向
Lua學習(二)物件導向
一、編譯執行與錯誤處理
(1)錯誤處理
在Lua中遇到任何未預期的條件都會引發一個錯誤,只要發生錯誤Lua就應該結束當前程式並返回應用程式。我們用error函式來輸出函式的錯誤資訊。下面是學習時用的程式碼:
print("______________________錯誤處理______________________________")
--條件不滿足時執行一些程式碼
--error是一個函式
local name="admin"
if name ~= "admin" then
error("NOT ADMIN")
end
--斷言,逗號前參數列示判斷條件,逗號後引數是條件不滿足時執行的error
assert(name=="張三","你不是張三,我要找的人是張三!")
執行的結果:
(2)捕獲錯誤——pcall
錯誤發生時不希望程式碼停止執行,可以使用pcall捕獲錯誤。
print("______________________錯誤捕獲______________________________")
function test()
-- body
print(a[1])
end
--pcall的作用是用來捕獲異常,有兩個返回值,第一個返回值表示狀態,第二個返回值表示返回的資訊,程式沒有出錯時message的值是nil
local status,message=pcall(test)
if status then
print("Success",message)
else
print(message)
end
執行結果:
(3)檔案載入
print("______________________檔案載入______________________________")
--loadfile只進行編譯,不執行。loadfile不會引發錯誤,只返回錯誤值,不做錯誤處理
loadfile("./hello,lua")
--dofil能夠執行hello.lua檔案中的程式碼,dofile寫幾次執行幾次
dofile("C:/Users/uesr/Desktop/LuaLearn/hello.lua")
for i=1,10 do
--require會儲存載入過的檔案,不會重複載入,第一次載入檔案時執行裡面的程式碼
--require是匯入一個模組,有返回值的,預設返回值boolean型別表示匯入成功或者失敗
--當require指令碼內部有返回值的時候,返回的就是對應的值
require("hello")
end
Hello()
hello檔案就輸出一句話:你好!因此執行結果是:你好!
二、元表與元方法
(1)元表與元方法的概念:
元表是普通的Lua表,定義了原始值在某些特定操作下的行為。例如,當table作為加法的運算元時,Lua檢查其元表中的“__add”欄位是否有個函式。如果 有,Lua呼叫它執行加法。我們稱元表中的鍵為事件(event),稱值為元方法(metamethod)。前述例中的事件是"__add",元方法是執行加法的函式。
print("____________元表_______________")
local metatable={
__add=function (t1,t2)
-- body
print("兩個相加時候呼叫")
end,
__sub=function (t1,t2)
-- body
print("兩個相減時候呼叫")
end
}
local t1={}
local t2={}
setmetatable(t1,metatable)
setmetatable(t2,metatable)
print(getmetatable(t1))
--相加的時候在metatable中查詢__add
local t3 = t1+ t2
--也可以將函式寫在元表外部
local mt = {}
mt.__add = function(s1, s2)
local result = ""
if s1.sex == "boy" and s2.sex == "girl" then
result = "完美的家庭。"
elseif s1.sex == "girl" and s2.sex == "girl" then
result = "不好";
else result = "不好"
end
return result
end
local s1 = {name = "Hello",sex = "boy"}
local s2 = {name = "Good",sex = "girl"}
-- 給兩個table設定新的元表
setmetatable(s1, mt);
setmetatable(s2, mt);
-- 進行加法操作
local result = s1 + s2;
print(result);
元表簡單的理解就是我們在獲取不存在元素時,會訪問元表中元方法,就類似其它語言中運算子過載的實現,沒有的功能我們進行擴充套件。
(2)算術類元方法
__add:加法 __sub:減法 __mul:乘法 __div:除法 __unm:相反數 __mod:取模 __pow:乘冪
注意元方法前面是兩個下劃線哦
(3)__index元方法
print("______________元方法__index(用於查詢)______________")
--查詢一個table裡面不存在的欄位的時候,會去元表裡面查詢__index
--__index是函式就呼叫該函式,是table就會在table裡面找,找不到為nil
local t={name="zhangsan"}
print(t.name,t.money)
local mt={
__index=function (table,key)
-- body
print("檢測到呼叫了不存在的欄位:",key)
end
}
setmetatable(t,mt)
print(t.money)
local mt1={
__index={money=999}
}
setmetatable(t,mt1)
print(t.money)
輸出結果:
(4)__newindex元方法
print("______________元方法__newindex(用於賦值)______________")
local newmt={
__index={money=999},
__newindex=function (t,k,v)
-- body
print(k.."不存在,不要對其進行賦值")
end
}
setmetatable(t,newmt)
--訪問table中的鍵不存在時,呼叫元表中__newindex元方法
t.money=1000
--__newindex並不能完成真正意義上的賦值,因此列印t.money還是會去元表中查詢__index方法
print(t.money)
執行結果:
有的時候我們想忽略元表__index和__newindex功能,就用rawget函式忽略元表中__index功效,用rawset函式忽略__newindex功效
三、全域性變數
print("____________________全域性變數____________________")
gName="我是全域性變數"
--用三種方式輸出變數的值
print(gName)
print(_G["gName"])
print(_G.gName)
print(type(_G))
執行結果:
四、模組呼叫
print("____________________模組呼叫____________________")
--可以理解成是單例模式,一般用於管理
require("./module")
game.setLevel(10)
print(game.getLevel())
module.lua檔案:
module("game",package.seeall)
local level=1
function setLevel(le)
level =le
end
function getLevel()
return level
end
function play()
print("Play")
-- body
end
function quit()
print("Quit")
-- body
end
五、物件導向
print("__________________Lua物件導向實現__________________")
TSprite={x=0,y=0}
function TSprite.setPosition(self,x,y)
self.x=x
self.y=y
end
function TSprite:setPosition(x,y)
self.x=x
self.y=y
end
local who=TSprite;
TSprite =nil
--.表示傳的時候要傳引數,:表示傳的時候預設有self(儘量使用:)
who.setPosition(who,1,2)
--等價於
who:setPosition(2,3)
print(who.x,who.y)
輸出結果
六、繼承實現
print("____________________繼承實現____________________")
Hero ={attack=0}
function Hero:new(o)
o=o or {}
setmetatable(o,self)
--單純的呼叫元表沒有意義,還需要找到元方法
self.__index=self
--通過找Hero表的元表元方法,查詢到不存在的值,還沒找到就是真沒有,可以理解是Hero表作為基類
return o
end
function Hero:skill(addAttack)
self.attack=self.attack+addAttack
end
--oneHero、twoHero可以理解成根據Hero表例項化的子類
oneHero=Hero:new({attack=100})
twoHero=Hero:new()
--這裡直接列印oneHero、twoHero表,能發現兩個表佔不同的記憶體空間,記憶體地址是不同的
print(oneHero)
print(twoHero)
oneHero:skill(10)
print(oneHero.attack)
--給子類oneHero加自己的方法,可以理解成是子類方法的擴充套件
function oneHero:test()
print("test")
end
function oneHero:injured(loseAttack)
if loseAttack>self.attack then
error"not engouth attack"
end
self.attack=self.attack-loseAttack/2
end
oneHero:injured(100)
print(oneHero.attack)-->60
oneHero:test()
輸出結果:
學習總結
在學習Lua語言中元表、元方法時多結合學過的其他語言中的思想,基本的實現思路是一樣的。物件導向思想雖然比較難但是很重要,需要多寫多想。
相關文章
- Lua學習筆記--物件導向(三)筆記物件
- Lua 中實現物件導向物件
- 學習Rust 物件導向Rust物件
- 大資料學習之路——java物件導向(二)大資料Java物件
- LUA基礎: TABLE, ARRAY, NAMESPACE, LUA的物件導向namespace物件
- PHP學習4——物件導向PHP物件
- JavaScript學習2:物件導向JavaScript物件
- Scala學習 2 Scala物件導向物件
- java學習——物件導向之繼承Java物件繼承
- 二、Java之物件導向Java物件
- JavaScript物件導向精要(二)JavaScript物件
- Flutter學習筆記(8)--Dart物件導向Flutter筆記Dart物件
- js高階 物件導向 學習筆記JS物件筆記
- Java SE 學習---物件導向程式設計Java物件程式設計
- Javascript 物件導向學習1 Function function ObjectJavaScript物件FunctionObject
- Ext學習筆記2-物件導向筆記物件
- 物件導向-物件導向思想物件
- java基礎二:物件導向Java物件
- 【python 物件導向】 python物件學習筆記《1》Python物件筆記
- 3. Struct 與 物件導向 |《 刻意學習 Golang 》Struct物件Golang
- Python 3 學習筆記之——物件導向Python筆記物件
- Python學習之物件導向程式設計Python物件程式設計
- 【C++】由Polocar 學習 C++物件導向C++物件
- PHP 物件導向 (二)類屬性PHP物件
- Java正式上路之物件導向二Java物件
- Javascript 物件導向程式設計(二)JavaScript物件程式設計
- javascript 物件導向學習(三)——this,bind、apply 和 callJavaScript物件APP
- Python學習之路——類-物件導向程式設計Python物件程式設計
- javascript ES5 物件導向的學習總結JavaScript物件
- Python學習筆記|Python之物件導向Python筆記物件
- 零基礎學Java第六節(物件導向二)Java物件
- 程式導向與物件導向物件
- 物件導向與程式導向物件
- “程序導向”和“物件導向”物件
- 複習java物件導向(封裝)Java物件封裝
- 物件導向物件
- Java課堂筆記(二):物件導向Java筆記物件
- 物件導向第二單元總結物件