Lua 中的 OOP - 创建类?

标签 oop lua

我知道这个网站上有一些关于在 Lua 中实现 OOP 的问题,但是,这个问题有点不同(至少与我发现的相比)。

我正在尝试创建一个名为“人类”的类,并使其使用“人类”的"new"构造函数创建的对象继承人类内部除构造函数之外的所有内容。然而,我也不希望能够在人类内部、人类身上使用方法。因此,人类类中的任何内容都只会传递给创建的对象。这是一个例子:

-- "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 的概念非常陌生,所以如果这是一个可怕的问题,我很抱歉。但如果有人能提供帮助,我将不胜感激。

最佳答案

我以前也遇到过同样的问题。你需要两张 table 。一种用于对象方法,一种用于类方法。将构造对象的元表设置为对象方法表。例如:

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

关于Lua 中的 OOP - 创建类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38805890/

相关文章:

Ruby - 包括两个模块,它们都有一个同名的子模块

recursion - 为什么这个递归函数参数为nil?

c++ - 创建一个回调结构以传递到 LuaJIT FFI

lua - lua 中的 table.remove 行为异常

oop - 特定时间段有效的业务规则——如何有序管理

oop - 一些可重用代码的架构

PHP 面向对象 - 真实案例

c# - 两个不同类的隐式运算符

c - 在 Windows 上理解 Lua 的 os.tmpname()

Lua 模式 - 魔兽世界 - 八零数据库 80wdb.com