Lua的物件導向 多重繼承 私密性

2022-09-02 10:36:12 字數 3609 閱讀 3361

本文**於:

在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的定義 類...