2016-08-06 3 views
2

이 사이트의 루아에서 OOP를 구현하는 것에 대해 몇 가지 질문이 있다는 것을 알고 있습니다 만,이 것은 조금 다릅니다 (최소한 내가 찾은 것과 비교했을 때). 루아의 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

이전에 같은 문제가 발생했습니다. 두 개의 테이블이 필요합니다. 하나는 객체 메소드 용이고 다른 하나는 클래스 메소드 용입니다. 생성 된 객체의 메타 테이블을 객체 메소드 테이블로 설정합니다.

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