Lua   发布时间:2022-04-12  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了如何在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);
    }
}@H_607_5@ 
 

这是我第一次尝试使用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({},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@H_607_5@

解决方法

这是代码的示例文字转录,有一个有用的类库,可以移动到另一个文件.

这绝不是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,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@H_607_5@ 
 

如果您坚持使用属性的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}@H_607_5@ 
 

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

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

大佬总结

以上是大佬教程为你收集整理的如何在Lua中创建类,子类和属性?全部内容,希望文章能够帮你解决如何在Lua中创建类,子类和属性?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。