如何在Lua中创建类、子类及其属性,实现复杂对象建模?

2026-04-01 19:181阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计841个文字,预计阅读时间需要4分钟。

如何在Lua中创建类、子类及其属性,实现复杂对象建模?

我在Lua上学习课程遇到困难。漫无目的的谷歌搜索引导我了解了关于元表的概念,并暗示第三方库是模拟/编写类所必需的。这是一个示例(仅因我在提供示例代码时得到了更好的答案)。

我很难在 Lua上学习课程.毫无结果的谷歌搜索引导我了解关于元表的想法,并暗示第三方库是模拟/编写类所必需的.

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

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的建议.但是,派生类的调用仍然会产生:“尝试调用方法’methodName'(一个零值)”

--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 这是代码的示例文字转录,有一个有用的类库,可以移动到另一个文件.

这绝不是Class的规范实现;随意定义您喜欢的对象模型.

Class = {} function Class:new(super) local class, metatable, properties = {}, {}, {} class.metatable = metatable class.properties = properties function metatable:__index(key) local prop = properties[key] if prop then return prop.get(self) elseif class[key] ~= nil then return class[key] elseif super then return super.metatable.__index(self, key) else return nil end end function metatable:__newindex(key, value) local prop = properties[key] if prop then return prop.set(self, value) elseif super then return super.metatable.__newindex(self, key, value) else rawset(self, key, value) end end function class:new(...) local obj = setmetatable({}, self.metatable) if obj.__new then obj:__new(...) end return obj end return class end ElectronicDevice = Class:new() function ElectronicDevice:__new() self.isOn = false end ElectronicDevice.properties.isOn = {} function ElectronicDevice.properties.isOn:get() return self._isOn end function ElectronicDevice.properties.isOn:set(value) self._isOn = value end function ElectronicDevice:Reboot() self._isOn = false self:ResetHardware() self._isOn = true end Router = Class:new(ElectronicDevice) Modem = Class:new(ElectronicDevice) function Modem:WarDialNeighborhood(areaCode) local cisco = Router:new() cisco:Reboot() self:Reboot() if self._isOn then self:StartDialing(areaCode) end end

如果您坚持使用属性的get / set方法,则不需要__index和__newindex函数,并且可能只有一个__index表.在这种情况下,模拟继承的最简单方法是这样的:

BaseClass = {} BaseClass.index = {} BaseClass.metatable = {__index = BaseClass.index} DerivedClass = {} DerivedClass.index = setmetatable({}, {__index = BaseClass.index}) DerivedClass.metatable = {__index = DerivedClass.index}

换句话说,派生类的__index表“继承”基类的__index表.这是有效的,因为Lua在委托__index表时,会有效地重复查找,因此调用了__index表的元方法.

另外,要小心调用obj.Method(…)vs obj:Method(…). obj:Method(…)是obj.Method(obj,…)的语法糖,混合这两个调用会产生异常错误.

如何在Lua中创建类、子类及其属性,实现复杂对象建模?

本文共计841个文字,预计阅读时间需要4分钟。

如何在Lua中创建类、子类及其属性,实现复杂对象建模?

我在Lua上学习课程遇到困难。漫无目的的谷歌搜索引导我了解了关于元表的概念,并暗示第三方库是模拟/编写类所必需的。这是一个示例(仅因我在提供示例代码时得到了更好的答案)。

我很难在 Lua上学习课程.毫无结果的谷歌搜索引导我了解关于元表的想法,并暗示第三方库是模拟/编写类所必需的.

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

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的建议.但是,派生类的调用仍然会产生:“尝试调用方法’methodName'(一个零值)”

--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 这是代码的示例文字转录,有一个有用的类库,可以移动到另一个文件.

这绝不是Class的规范实现;随意定义您喜欢的对象模型.

Class = {} function Class:new(super) local class, metatable, properties = {}, {}, {} class.metatable = metatable class.properties = properties function metatable:__index(key) local prop = properties[key] if prop then return prop.get(self) elseif class[key] ~= nil then return class[key] elseif super then return super.metatable.__index(self, key) else return nil end end function metatable:__newindex(key, value) local prop = properties[key] if prop then return prop.set(self, value) elseif super then return super.metatable.__newindex(self, key, value) else rawset(self, key, value) end end function class:new(...) local obj = setmetatable({}, self.metatable) if obj.__new then obj:__new(...) end return obj end return class end ElectronicDevice = Class:new() function ElectronicDevice:__new() self.isOn = false end ElectronicDevice.properties.isOn = {} function ElectronicDevice.properties.isOn:get() return self._isOn end function ElectronicDevice.properties.isOn:set(value) self._isOn = value end function ElectronicDevice:Reboot() self._isOn = false self:ResetHardware() self._isOn = true end Router = Class:new(ElectronicDevice) Modem = Class:new(ElectronicDevice) function Modem:WarDialNeighborhood(areaCode) local cisco = Router:new() cisco:Reboot() self:Reboot() if self._isOn then self:StartDialing(areaCode) end end

如果您坚持使用属性的get / set方法,则不需要__index和__newindex函数,并且可能只有一个__index表.在这种情况下,模拟继承的最简单方法是这样的:

BaseClass = {} BaseClass.index = {} BaseClass.metatable = {__index = BaseClass.index} DerivedClass = {} DerivedClass.index = setmetatable({}, {__index = BaseClass.index}) DerivedClass.metatable = {__index = DerivedClass.index}

换句话说,派生类的__index表“继承”基类的__index表.这是有效的,因为Lua在委托__index表时,会有效地重复查找,因此调用了__index表的元方法.

另外,要小心调用obj.Method(…)vs obj:Method(…). obj:Method(…)是obj.Method(obj,…)的语法糖,混合这两个调用会产生异常错误.

如何在Lua中创建类、子类及其属性,实现复杂对象建模?