2010-05-30 63 views
1

簡單的Lua的遊戲簡單的類,像這樣:Lua的類的實例與嵌套表

creature = class({ 
name = "MONSTER BADDY!", 

stats = { power = 10, agility = 10, endurance = 10, filters = {} }, 

other_things = ... 
}) 

creatureA = creature.new() 

creatureB = creature.new() 

creatureA.name = "Frank" 

creatureB.name = "Zappa" 

creatureA.stats.agility = 20 

creatureB.stats.power = 12 

- 等等等等

非表值是個人每個實例,但表中的值之間共享 所有的情況下,如果我在一個實例修改stats.X值, 所有其他情況下看到相同的統計數據表格。

Q1:我的OO實現有缺陷?我試圖LOOP和發生相同的結果, 有沒有在我的邏輯的根本缺陷?

Q2:你如何有生物的每個實例有它自己的統計數據表(和分表)?

PS。我不能將我的類表弄平,因爲它比示例稍微複雜一些,並且使用此嵌套表實現簡化了代碼的其他部分。

+1

此外,你並不需要在函數調用類中的括號內。 class {} == class({})。 – Puppy 2010-05-30 10:30:17

回答

0

創建新的creature時,如果您不希望它被共享,則始終可以爲其創建一個新的stats表。

creature = class({ 
    name = "MONSTER BADDY!", 
    stats = stats.new({ power = 10, agility = 10, endurance = 10, filters = {} }), 
    other_things = ... 
}) 

在構造函數stats中,權力,敏捷性等將作爲參數傳遞。

2

它的工作原理一樣,因爲類實例具有類表設置爲自己的元表__index(當然,大多數實現工作方式) 所以,如果你訪問creatureA.stats(它無法找到creatureAstats,從而降低到__index)返回creature.stats。 也許你應該對Lua 5.1 Reference Manual: Metatables

讀了你將無法在類的表構造申報每個實例變量(除非你深拷貝一切從類表到該實例,這將是相當昂貴)

你必須做到在任何初始化函數的類實現使用:

creature = class 
{ 
    __init = function(self, ...) 
     self.stats = {power = 10, agility = 10, endurance = 10, filters = {}} 
    end, 
} 
3

class不是在Lua的標準功能。你不會說你是從羅伯託那裏借來的,是自己推出的還是什麼的。但我的猜測是,你想改變new方法,以便它的原型,而不是淺拷貝的深拷貝

function deep_copy(v) 
    if type(v) == 'table' then 
    local u = { } 
    for k, v in pairs(v) do 
     u[k] = v 
    end 
    setmetatable(u, getmetatable(v)) 
    return u 
    else 
    return v 
    end 
end 

(警告:我還沒試過編譯這段代碼,更不用說運行它。)

0

該函數的你叫看起來很可疑。我會盡可能簡單的代碼。這是一個怪物類文件。沒有什麼花哨的,有些人會說它缺乏一些絨毛,但至少我可以在下週自己閱讀代碼。

-- Class object 

monster = {} 
monster.__index = monster 

-- Class methods 

function monster.new(name) 
    local o = {} 
    o.name = name 
    o.stats = {power = 10, agility = 10, endurance = 10, filters = {}} 
    setmetatable(o, monster) 
    return o 
end 

function monster:shout() 
    print('Aaaaaaa! My name is ' .. self.name .. '!') 
end 

這裏是輸出:

> lua 
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio 
> require 'monster' 
> m = monster.new('Katla') 
> m:shout() 
Aaaaaaa! My name is Katla!