class - 如何在 Lua 中创建类、子类和属性?

标签 class lua

我很难在 Lua 中学习类(class).毫无结果的谷歌搜索让我想到了关于元表的想法,并暗示第三方库是模拟/编写类所必需的。

这是一个示例(只是因为我注意到当我提供示例代码时我得到了更好的答案):

public class ElectronicDevice
{
    protected bool _isOn;
    public bool IsOn { get { return _isOn; } set { _isOn = value; } }
    public  void Reboot(){_isOn = false; ResetHardware();_isOn = true; }
}

public class Router : ElectronicDevice
{
}

public class Modem :ElectronicDevice
{
    public void WarDialNeighborhood(string areaCode)
    {
        ElectronicDevice cisco = new Router();
        cisco.Reboot();
        Reboot();
        if (_isOn)
            StartDialing(areaCode);
    }
}

这是我第一次尝试使用 Javier 建议的技术来翻译上述内容。

我接受了RBerteig的建议。但是,对派生类的调用仍然产生:"attempt to call method 'methodName' (a nil value)"
--Everything is a table
ElectronicDevice = {};

--Magic happens
mt = {__index=ElectronicDevice};

--This must be a constructor
function ElectronicDeviceFactory ()
    -- Seems that the metatable holds the fields
    return setmetatable ({isOn=true}, mt)
end

-- Simulate properties with get/set functions
function ElectronicDevice:getIsOn()  return self.isOn end
function ElectronicDevice:setIsOn(value)  self.isOn = value end
function ElectronicDevice:Reboot() self.isOn = false;
    self:ResetHardware(); self.isOn = true; end
function ElectronicDevice:ResetHardware()  print('resetting hardware...') end

Router = {};
mt_for_router = {__index=Router}

--Router inherits from ElectronicDevice
Router = setmetatable({},{__index=ElectronicDevice});

--Constructor for subclass, not sure if metatable is supposed to be different
function RouterFactory ()
    return setmetatable ({},mt_for_router)
end

Modem ={};
mt_for_modem = {__index=Modem}

--Modem inherits from ElectronicDevice
Modem = setmetatable({},{__index=ElectronicDevice});

--Constructor for subclass, not sure if metatable is supposed to be different
function ModemFactory ()
    return setmetatable ({},mt_for_modem)
end

function Modem:WarDialNeighborhood(areaCode)
        cisco = RouterFactory();
        --polymorphism
        cisco.Reboot(); --Call reboot on a router
        self.Reboot(); --Call reboot on a modem
        if (self.isOn) then self:StartDialing(areaCode) end;
end

function Modem:StartDialing(areaCode)
    print('now dialing all numbers in ' .. areaCode);
end

testDevice = ElectronicDeviceFactory();
print("The device is on? " .. (testDevice:getIsOn() and "yes" or "no") );
testDevice:Reboot(); --Ok

testRouter = RouterFactory();
testRouter:ResetHardware(); -- nil value

testModem = ModemFactory();
testModem:StartDialing('123'); -- nil value

最佳答案

在 Lua 中做类 OOP 真的很容易;只需将所有“方法”放入 __index元表的字段:

local myClassMethods = {}
local my_mt = {__index=myClassMethods}

function myClassMethods:func1 (x, y)
    -- Do anything
    self.x = x + y
    self.y = y - x
end

............

function myClass ()
    return setmetatable ({x=0,y=0}, my_mt)

就个人而言,我从来不需要继承,所以以上对我来说就足够了。如果还不够,您可以为方法表设置一个元表:
local mySubClassMethods = setmetatable ({}, {__index=myClassMethods})
local my_mt = {__index=mySubClassMethods}

function mySubClassMethods:func2 (....)
    -- Whatever
end

function mySubClass ()
    return setmetatable ({....}, my_mt)

更新:
您更新的代码中有错误:
Router = {};
mt_for_router = {__index=Router}
--Router inherits from ElectronicDevice
Router = setmetatable({},{__index=ElectronicDevice});

请注意,您初始化 Router , 并构建 mt_for_router由此;但随后您重新分配 Router到新表,而 mt_for_router还是指向原来的Router .

替换 Router={}Router = setmetatable({},{__index=ElectronicDevice}) (在 mt_for_router 初始化之前)。

关于class - 如何在 Lua 中创建类、子类和属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1092832/

相关文章:

C# : Mini Application Structural Design (Classes/Interfaces/etc. )

java - 迭代期间 HashSet NullPointerException 错误

c++ - Lua 用户数据指针的生命周期

function - Lua 函数的帮助

lua - 获取用于在 Lua 中创建协程/线程的函数

C++ 编译器错误递归模板

c++ - 指向对象数组中函数的指针数组

C++默认参数类成员

c++ - 在头文件中编写的类的成员函数的定义,在 C++ 中单独的 .cpp 文件中

lua - 我如何使用外部文件作为 Lua 中的表?