2016-08-06 31 views
2

我知道有一些關於在Lua上實現OOP的問題,但是,這個有點不同(至少與我發現的相比)。Lua中的OOP - 創建一個類?

我正在嘗試創建一個名爲「」的人類,並使其使用「人類」的「新」構造函數創建的對象繼承了除人類構造函數之外的所有內容。但是,我也不想在人體內使用方法。所以無論在人類內部,只傳遞給創建的對象。這裏有一個例子:

-- "Human" class 
human = {} 

function human.new(name) 
    local new = {} -- New object 

    -- Metatable associated with the new object 
    local newMeta = 
    { 
     __index = function(t, k) 
      local v = human[k] -- Get the value from human 
      print("Key: ", k) 
      if type(v) == "function" then -- Takes care of methods 
       return function(_, ...) 
        return v(new, ...) 
       end 
      else 
       return v -- Otherwise return the value as it is 
      end 
     end 
    } 

    -- Defaults 
    new.Name = name 
    new.Age = 1 

    return setmetatable(new, newMeta) 
end 

-- Methods 
function human:printName() 
    print(self.Name) 
end 

function human:setAge(new) 
    self.Age = new 
end 

-- Create new human called "bob" 
-- This works as expected 
local bob = human.new("Bob") 
print(bob.Name) -- prints 'Bob' 
bob:printName() -- prints 'Bob' 
bob:setAge(10) -- sets the age to 10 
print(bob.Age) -- prints '10' 

-- But I don't want something like this allowed: 
local other = bob.new("Mike") -- I don't want the constructor passed 

-- I'd also like to prevent this from being allowed, for "human" is a class, not an object. 
human:printName() 

因此,與human.new("Bob")創建對象工作正常,但它也通過構造函數中,我仍然可以使用該對象的類方法。我對OOP的概念很陌生,所以如果這是一個可怕的問題,我很抱歉。但如果有人可以幫忙,我會很感激。

+0

退房['base'(https://github.com/Okahyphen/base)如果你正在尋找這一個很好的基礎,之類的事情。 [源代碼](https://github.com/Okahyphen/base/blob/master/src/base.lua)非常明瞭,可能會提供一些見解。 – Oka

回答

4

我以前遇到同樣的問題。你需要兩張桌子。一個用於對象方法,另一個用於類方法。將構造對象的metatable設置爲對象方法表。例如:

local Class = {} 
local Object = {} 
Object.__index = Object 

function Class.new() 
    return setmetatable({}, Object) 
end 
setmetatable(Class, {__call = Class.new}) 

function Object.do() 
    ... 
end 

return Class 

而且使用它

Class = require('Class') 

local obj = Class.new() -- this is valid 
obj.do()    -- this is valid 
obj.new()    -- this is invalid 
Class.do()    -- this is invalid 
+0

非常感謝,感謝您的時間。 – William