简体   繁体   English

Lua中的OOP-创建课程?

[英]OOP in Lua - Creating a class?

I'm aware there are a few questions about implementing OOP in Lua on this site, however, this one is a bit different (at least compared to what I found). 我知道在此站点上有一些关于在Lua中实现OOP的问题,但是,这有点不同(至少与我发现的情况相比)。

I'm trying to create a class called " human ", and make it so objects created with the "new" constructor of "human", inherit everything inside human except it's constructor. 我正在尝试创建一个名为“ human ”的类,并使其使用“ human ”的“ new”构造函数创建的对象继承除human之外的所有构造函数。 However, I also don't want to be able to use methods inside of human, on human. 但是,我也不想在人类内部使用人类内部的方法。 So whatever's inside the human class, is only passed to created objects. 因此,人类类内部的任何内容都只会传递给创建的对象。 Here's an example: 这是一个例子:

-- "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 creating the object with human.new("Bob") works fine, but it also passes the constructor, and I can still use the object methods on the class. 因此,使用human.new("Bob")创建对象可以很好地工作,但是它也可以通过构造函数,并且我仍然可以在类上使用对象方法。 I'm very new to the concept of OOP, so I'm sorry if this was a horrible question. 我对OOP的概念很陌生,因此如果这是一个可怕的问题,我感到抱歉。 But if anyone could help, I'd appreciate that. 但是,如果有人可以提供帮助,我将不胜感激。

I have run into the same issue before. 我以前也遇到过同样的问题。 You need two tables. 您需要两个表。 One for object methods and one for class methods. 一种用于对象方法,一种用于类方法。 Set the metatable of constructed objects to the object method table. 将构造对象的元表设置为对象方法表。 For example: 例如:

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

And use it 并使用它

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM