本文**於:
在lua中的多重繼承和私密性可能用得比較少,也可能只是我個人用得比較少。
本來想偷懶不寫這文章的,因為我今天剛買了個漂移板,連起步都還沒學會啊,想多學一會。
咳咳,本著堅持不懈、負責到底的態度,我還是決定隨便寫幾句~(小若:隨便寫幾句是幾噸意思啊?!)
我發現這些高(shen)智(jing)商(bing)人群真的很厲害,這種技巧都能想到,很佩服。
其實多重繼承沒什麼特別的,除非兩個將要被繼承的類有相同的函式名和屬性,否則,處理起來很簡單。
那麼,單繼承與多重繼承的差別也在這裡,乙個是只查詢乙個table,另乙個是查詢兩個或以上的table。
我們就先來看看如何從2個或多個table中查詢某個字段,如下**:
function search(classes, key)for i = 1, #classes do
local value =classes[i][key];
if value ~=nil then
return
value;
endend
endlocal t1 = ;
local t2 = ;
print(search(,
"game
"));
這裡的classes引數,是乙個table,這個table裡又存放了多個table,也就是我們想要繼承的那些類。
而key就是要查詢的字段。
輸出結果如下:
[lua-print] who
剛剛的search函式很簡單吧?別急著開心,那只是預熱一下而已,真正建立多重繼承的函式比較複雜。
如下**:
function createclass(...)local parents =;
local child ={};
--設定類的元表
setmetatable(child, )
--給類新增乙個new函式,用於建立物件
function child:
new()
o ={};
setmetatable(o, child);
child.__index =child;
return
o; end
--返回這個繼承了多個類的子類
return
child;
end
createclass函式就是用來建立乙個繼承了多個類的子類,有點小複雜,慢慢分析:
1) 引數是乙個可變引數,我們要將多個被繼承的類作為引數傳遞進來
2) parents用於儲存這些被繼承的類
4) 給child設定元表,並且設定__index元方法,__index元方法可以是乙個函式,當它是乙個函式時,它的引數就是元表所屬的table,以及要查詢的欄位名。
5) 我們在__index元方法函式裡呼叫search函式,從多個父類中查詢所需的字段。於是,當呼叫child的某個函式時,就會從各個父類中查詢,這已經完成了繼承的工作了。
7) 最後返回child,一切都完成了。
看似很複雜,其實還是對__index的應用而已。
我們趕緊來測試一下吧,如下**:
--乙個精靈類tsprite ={}
function tsprite:hello()
print(
"誰跟你hello!");
endfunction tsprite:
new()
o ={}
setmetatable(o, self);
self.__index =self;
return
o; end
--乙個子彈類
tbullet ={}
function tbullet:fire()
print(
"別動,再動我就瞄不准了!");
endfunction tbullet:
new()
o ={}
setmetatable(o, self);
self.__index =self;
return
o; end
--繼承了兩個類的子類
local bulletsprite =createclass(tsprite, tbullet);
--子類的物件
local bsprite = bulletsprite:new
(); bsprite:hello();
bsprite:fire();
這裡建立了兩個類:tsprite和tbullet。
然後呼叫createclass函式,建立乙個繼承了tsprite和tbullet的子類。
最後建立子類的物件,呼叫物件的hello和fire函式。
輸出結果如下:
[lua-print] 誰跟你hello![lua-print] 別動,再動我就瞄不准了!
然後,lua裡是沒有私密這種說法的,類也是乙個table,table的所有欄位都是可以呼叫的,並沒有說哪些是公有的,哪些是私有的。
如果有某些函式和屬性不希望被外部呼叫,那麼,也可以,不過這種實現方式看起來很彆扭:
function createtsprite()local self = ;
local function mybus()
print(
"mybus是我自己的函式,你不能直接呼叫");
endlocal function mygame()
print(
"mygame是我自己的函式,你不能直接呼叫");
endlocal function hello()
print(
"hello:");
mybus();
endlocal function hi()
print(
"hi:");
mygame();
endlocal function setname(newname)
self.name =newname;
endreturn ;
end
我們已經不需要用到冒號來定義函式了,這個類的name、mybus、mygame都是不希望給外部直接呼叫的。
來看看測試**:
local sp =createtsprite();sp.hello();
sp.hi();
輸出結果如下:
[lua-print] hello:[lua-print] mybus是我自己的函式,你不能直接呼叫
[lua-print] hi:
[lua-print] mygame是我自己的函式,你不能直接呼叫
這樣,我們建立的物件就只能使用hello、hi、setname函式。
而其他的name、mybus、mygame只能通過這幾個能使用的函式去呼叫,而不能直接呼叫。
這樣就能完成私密性了。
不過,我個人有點迷糊,因為這已經不太像乙個類的樣子了。
可能介紹的都比較基礎,目的是為了鞏固lua基礎。
lua物件導向(繼承及多繼承)
還是個人感覺,lua輕量簡潔的語法,正式在於表這種類似於物件的使用,表 t 不使用 funtion t.add self,x self.a self.a x 結束t.add 5 t 使用 函式t add x self.a self.a x 結束t 新增 5 帳戶 父類 函式account new o...
物件導向程式設計 多重繼承(七)
1.繼承 繼承 至少兩個類,表達的是什麼是什麼的關係。繼承存在單繼承和多繼承。子類要是沒有 init 就呼叫父類的,子類要是有 init 就呼叫自己的,也可以引用父類的。class animal object def init self,name,aggressivity,life value se...
LUA物件導向程式設計(二)繼承
在lua中模擬類的繼承行為,可以通過setmetatable方法來實現。首先,我們就先實現乙個基類vehicle,然後再定義該基類的乙個子類bicycle,基類的定義與之前介紹的類的定義方法是一致的,如果你對此還不是很熟悉,可以先回顧一下 lua物件導向程式設計 一 類 基類vehicle的定義 類...