Lua 中的面向对象编程——创建类

我知道这个网站上有一些关于在 Lua 中实现面向对象编程的问题,但是这个问题有点不同(至少与我找到的相比)。

我试图创建一个叫做“_human_”的类,并使使用“human”构造函数创建的对象继承 human 中的所有内容,但不继承构造函数。但是,我也不想在 human 中使用方法对 human 对象有影响。因此,human 类中的所有内容仅传递给创建的对象。下面是一个例子:

-- “Human” 类
human = {}

function human.new(name)
    local new = {} -- 新对象

    -- 与新对象相关联的元表
    local newMeta =
    {
        __index = function(t, k)
            local v = human[k] -- 从 human 中获取值
            print("Key: ", k)
            if type(v) == "function" then -- 处理方法
                return function(_, ...)
                    return v(new, ...)
                end
            else
                return v -- 否则返回该值本身
            end
        end
    }

    -- 默认设置
    new.Name = name
    new.Age = 1

    return setmetatable(new, newMeta)
end

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

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

-- 创建一个名为 “bob” 的新 human
-- 这能够正常工作
local bob = human.new("Bob")
print(bob.Name) -- 打印 'Bob'
bob:printName() -- 打印 'Bob'
bob:setAge(10) -- 将年龄设置为 10
print(bob.Age) -- 打印 '10'

-- 但我不希望允许这样的操作:
local other = bob.new("Mike") -- 我不想传递构造函数

-- 我也希望阻止这种操作,因为“human”是一个类,而不是一个对象。
human:printName()

使用 human.new("Bob") 创建对象可以正常工作,但仍会传递构造函数,并且我仍然可以在类上使用对象方法。我对 OOP 概念非常陌生,所以如果有人能帮忙解决这个问题,我将不胜感激。

点赞
用户6614127
用户6614127

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

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() -- 这是有效的
obj.do()                -- 这是有效的
obj.new()               -- 这是无效的
Class.do()              -- 这是无效的
2016-08-06 15:55:27