【问题标题】:How to implement Lua OOP in my example?如何在我的示例中实现 Lua OOP?
【发布时间】:2014-08-01 05:52:02
【问题描述】:

我正在尝试在 Lua 中创建一个类,其中包含有关该类关注者的信息,并且我还希望关注的类了解他的关注者。

但是我的代码失败了,我不知道为什么。

错误是

lua: OOP.lua:90: 尝试调用方法 'getName'(一个 nil 值)

Vehicle = {}

--------
--FIELDS
--------
Vehicle.name = ""
Vehicle.vtype = "";
Vehicle.follower = {};
Vehicle.leader = {};

---------------------
--SETTERS AND GETTERS
---------------------

function Vehicle:setName(value)
    self.name = value
end
function Vehicle:getName()
    return self.name
end

function Vehicle:setType(value)
    self.vtype = value
end

function Vehicle:getType()
    return self.vtype
end

function Vehicle:setFollower(pVeh)
    self.follower = {};
    self.follower = pVeh;
end;

function Vehicle:getFollower()
    return self.follower;
end;

function Vehicle:getLeader()
    return self.leader;
end;

function Vehicle:setLeader(pVeh)
    self.leader = pVeh;
    if (self.leader ~= nil) then
        print ("-- setted leader! --");
    end;
end;

-----------
--METHODS--
-----------

function Vehicle:follow(pVeh)  --> why does this not work?
    self:setLeader(pVeh);
    pVeh:setFollower(self);
end;


-- constructor
function newVehicle(pNm,pTp)
    tbl = {}
    setmetatable(tbl, {__index = Vehicle});
    tbl:setName(pNm);
    tbl:setType(pTp);
    return tbl
end
-----------------------------------------------
-- TEST
-----------------------------------------------
local car1 = newVehicle("Mazda","Car");
local car2 = newVehicle("Harley","Bike");
print("--------------");
print (car1:getName()); --> prints "Mazda"
print (car2:getName()); --> prints "Harley"
car2:follow(car1)
print ("Leader of " .. car1:getName() .. " is " .. car1:getLeader():getName())

【问题讨论】:

    标签: oop lua


    【解决方案1】:

    据我所见,问题出在您的测试代码中:

    print ("Leader of " .. car1:getName() .. " is " .. car1:getLeader():getName())
    

    car1 没有定义领导者。 (你做了car2:follow(car1)

    一些提示:

    • 需要在创建方法中定义字段表。这还不适用于您的代码,但假设您想做排。您可以执行Vehicle.platoon = {}; Tank1.platoon[Tank2] = true 之类的操作——这会将 Tank2 添加到 Vehicle 的排表中,并与每辆车共享。如果您在新方法中定义它:function newVehicle(...) tbl.platoon = {} ... end,那么它对每辆车都是唯一的。

    • 除非您有充分的理由使用它们,否则不要使用访问器(get*、set*)方法。它们增加了混乱,并且不利于性能。使用它们的一个很好的理由是,如果您正在访问器方法中访问一个表,并且想要简化与它的交互。 (即Obj:addChild(Obj2)obj:hasChild(Obj2))但是它可能不再有资格作为访问器了:)

    • 您可以对未设置的字段使用虚拟对象。这将防止像您这样的错误:

      local Dummy = newVehicle("None", "None")
      Vehicle.follower = Dummy
      Vehicle.leader = Dummy
      

    在您的代码中,这会产生:

    --------------
    Mazda
    Harley
    -- setted leader! --
    Leader of Mazda is None
    

    【讨论】:

    • 这个错误让你分心了,我以前也遇到过。也要非常小心__index 中的表格,因为它们是参考 :)
    【解决方案2】:
    car2:follow(car1)
    

    car1car2 关注。鉴于,后来;您正在尝试访问 car1 的领导者,当然返回 nil。因此出现错误。

    print( "Follower of "..car1:getName().." is "..car1:getFollower():getName() )
    

    【讨论】:

      猜你喜欢
      • 2017-03-15
      • 1970-01-01
      • 1970-01-01
      • 2014-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多