我很难在 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/