2016-08-06 35 views
2

Ich bin mir bewusst, ein paar Fragen über die Implementierung von OOP in Lua auf dieser Seite gibt es jedoch, das ist ein etwas anders (zumindest im Vergleich zu dem, was ich gefunden).OOP in Lua - Erstellen einer Klasse?

Ich versuche, eine Klasse namens "menschlichen" zu erstellen, und machen Sie es so Objekte mit dem "neuen" Konstruktor von "Mensch" erstellt, erben Sie alles in Mensch außer seinem Konstruktor. Ich möchte aber auch keine Methoden im Menschen, im Menschen anwenden können. Was immer in der menschlichen Klasse ist, wird nur an erstellte Objekte weitergegeben. Hier ein Beispiel:

-- "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() 

So Erstellen Sie das Objekt mit human.new("Bob") funktioniert gut, aber es geht auch den Konstruktor, und ich kann immer noch die Objektmethoden auf die Klasse. Ich bin sehr neu in dem Konzept von OOP, also tut es mir leid, wenn das eine schreckliche Frage war. Aber wenn jemand helfen könnte, würde ich das schätzen.

+0

Check out [ 'base'] (https://github.com/Okahyphen/base), wenn Sie dieses für eine schöne Grundlage freuen Art der Sache. Der [Quellcode] (https://github.com/Okahyphen/base/blob/master/src/base.lua) ist ziemlich selbsterklärend und könnte einige Einsichten liefern. – Oka

Antwort

4

Ich habe, bevor sie in das gleiche Problem laufen. Sie benötigen zwei Tabellen. Eine für Objektmethoden und eine für Klassenmethoden. Setzen Sie das Metatable der konstruierten Objekte auf die Objektmethodentabelle. Zum Beispiel:

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 

und verwenden Sie es

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

Vielen Dank, schätzen Sie Ihre Zeit. – William