从Luaj继承Java类

在 Luaj 中,是否可以让 Lua 类继承 Java 类?我尝试在绑定的类上使用 getmetatable(),但似乎它返回了 nil

这里,Wizard 是一个绑定到 Lua 的 Java 类,而 SetupWizard 是我想从 Wizard 继承的 Lua 类。

function SetupWizard:new()
    local self = setmetatable({}, getmetatable(Wizard))
    return self
end

__index 赋值为 Wizard 的值也不起作用。

SetupWizard 定义:

SetupWizard = {
    host = nil,
    user = nil,
    password = nil,
    database = nil,
    mySqlTables = {
        users = nil,
    },
}
SetupWizard.__index = Wizard

... 在此处编写 SetupWizard 方法
点赞
用户4179502
用户4179502

LuaJ 相对灵活,比如在引入 Java 类方面有多种方式。

你并没有说明你是如何引入 Java 类的,因此我假设你通过创建一个Java 函数库 作为桥梁来构建模块。你可以通过 require"moduleName" 引入它,如下所示:

import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;

/*
 * 当 require"module name" 被调用时,在 LuaJ 中它也会搜索 Java 类,如果类名与给定的模块名称匹配,
 * 且继承了 LuaFunction 并且有默认构造函数,那么它将调用 call(LuaValue moduleName, LuaValue globalEnviroment) 方法,
 * 并将模块名称字符串和全局环境作为 LuaValues 传递给它,将此调用的返回值作为自己的返回值。
 *
 */

public class Example extends TwoArgFunction{

    @Override
    public LuaValue call(LuaValue modname, LuaValue globalEnv) {
        // 创建一个表来放置所有我们的函数
        LuaValue table = LuaValue.tableOf();

        // 在表中设置值“name”为 example。这在 example 方法中使用
        table.set("name", "example");
        // 在表中设置值“exampleMethod”,为我们下面创建的类型为 OneArgFunction 的类
        table.set("exampleMethod", exampleMethod);

        // 最后返回我们的表。这个值然后将被 require 返回。
        return table;
    }

    /* 创建一个有一个参数 self 的函数。

      这模拟了在 Lua 中创建一个方法,并且可以被调用,当被添加到表中时,可以像这样被调用:table:exampleMethod()。
      这是因为在 Lua 中,冒号语法糖用于 object.function(object)。

    */
    OneArgFunction exampleMethod = new OneArgFunction() {

        @Override
        public LuaValue call(LuaValue self) {

            if(self.istable()) {
                return self.get("name");
            }

            return NIL;
        }
    };

}

然后,你可以在 Lua 代码中这样使用它:

-- 引入我们创建的 Wrapper 类
example = require"Example"
-- 打印调用 exampleMethod 的返回值
print("The name of the class is: "..example:exampleMethod())

-- 然后像这样使用索引
example2 = setmetatable({},{__index=example})

example2.name = "example2"

print("The name of the class is: "..example2:exampleMethod())

如我在答案开头所述,LuaJ 相对灵活,具体怎样实现可以有多种方式。由于我的声望不够,我无法发表评论询问您如何在 LuaJ 中引入 Java 类,欢迎在此答案下评论进行澄清。

2014-11-03 17:08:14
用户3175859
用户3175859

你的基于 Java 的 LuaJ 模块需要返回一个表格,并且你使用了以下代码:

local SetupWizard = require("SetupWizard")
local Wizard = {}
setmetatable(Wizard, {__index=SetupWizard})
--optionally create single metatable for all Wizard instances: local wizardMetaTable = {_index=Wizard}
function Wizard:new()
  local T = {}
  setmetatable(T, {__index=Wizard})
  -- setmetatable(T, wizardMetaTable)
  -- this increases performance by using one metatable for all wizards.
  return T
end
2015-03-08 23:26:32