0

是否可以在Codea中使用继承?虽然我对 Lua 还很陌生,但通过一些快速的谷歌搜索,看起来做继承和多态的方法有点“涉及”。有什么技术可以安全地与 Codea 的 Lua 托管引擎一起使用吗?


这是一个简单的可运行测试,我正在尝试开始工作。我的超类:

Superklass = class()

function Superklass:init(x,y)
    self.x = x
    self.y = y
end

function Superklass:debug()
    print(string.format("(%d, %d)", self.x, self.y))
end

一个子类:

Ship = class()

function Ship:init(x, y)
    -- you can accept and set parameters here
    print('ship:init() called')

    self = Superklass(x,y) -- ???
    print('attempting to call self:debug()')
    self:debug() -- works! prints  
    print('ok!')
end

function Ship:draw()
    print('ship:draw() called')
    
    print('attempting to call self:debug()')
    self:debug()
    print('ok')
end

和程序入口点:

-- initial setup
function setup()
    ship = Ship(HEIGHT/2, WIDTH/2)
end

-- called once every frame
function draw()
    ship:draw()
end

这是运行的输出:

ship:init() called
attempting to call self:debug()
(384, 375)
ok!
ship:draw() called
attempting to call self:debug()
error: [string "Ship = class()..."]:16: attempt to call method 'debug' (a nil value)
Pausing playback

我敢肯定这是非常幼稚的——但我希望能在 Codea 的上下文中发挥作用的方向上的提示。

4

2 回答 2

3

只是为了给出一个可行的解决方案(Codea 中的类继承)并指出一些陷阱。首先,我应该注意 Codea 以 Tab 顺序加载类,因此超类的选项卡必须在子类的选项卡之前。我建议在 Codea 论坛上查看此主题。它讨论了下面的技术,并提供了一些关于底层机制的见解。

首先,我们定义一个超类AbstractSprite,其构造函数采用 (x,y) 坐标。它提供了一种方法调试来将此坐标回显到控制台。

AbstractSprite = class()

function AbstractSprite:init(x,y)
    self.position = vec2(x,y)
    
    print("new AbstractSprite created")
end

function AbstractSprite:debug()
    print(string.format("(%d,%d)", self.position.x, self.position.y))
end

接下来,我们定义一个实现类Ship,它实现了一个调用super的自定义调试,演示了如何向上移动类层次结构。

Ship = class(AbstractSprite)

function Ship:init()
    AbstractSprite.init(self)
    print("new Ship created")
end

function Ship:debug()
    print("I am a ship, calling my superclasses' methods!")
    AbstractSprite.debug(self)
end

程序入口点。我们创建了一个Ship和一个“原始” AbstractSprite,分别调用 debug :

function setup()
    ship = Ship()
    ship:debug()
    
    asteroid = AbstractSprite(150, 200)
    asteroid:debug()
end

和控制台输出:

new AbstractSprite created
new Ship created
I am a ship, calling my superclasses' methods!
(0,0)
new AbstractSprite created
(150,200)
于 2012-04-29T20:32:06.880 回答
2

免责声明:我是middleclass的作者,Lua 的 OO-lib。

您在第一个示例中指出的基于闭包是一个很好的智力练习,但它几乎没有实用价值。在 Lua 中,使用表格可以更好地实现面向对象(正如您的第二个示例所指出的示例所暗示的那样) - 它以更快的速度提供等效的功能。唯一的区别是语法。

有很多库使用标准的基于表的方法在 Lua 中执行 OO。你可以在这里找到一个列表:

http://lua-users.org/wiki/ObjectOrientedProgramming

使用中间类,你的代码会变成这样:

require 'middleclass'

-- middleclass needs the class name as a parameter
SuperClass = class('SuperClass') -- I don't see the point of using a K here, BTW

function SuperClass:initialize(x,y) -- initialize instead of init
    self.x = x
    self.y = y
end

function SuperClass:debug()
    print(string.format("(%d, %d)", self.x, self.y))
end
--

Ship = class('Ship', SuperClass) -- notice that we put the superclass here

function Ship:initialize(x, y) -- initialize instead of init again
    -- you can accept and set parameters here
    print('ship:initialize() called')

    self = SuperClass.initialize(self,x,y) -- notice the extra self and initialize here
    print('attempting to call self:debug()')
    self:debug() -- works! prints  
    print('ok!')
end

function Ship:draw()
    print('ship:draw() called')

    print('attempting to call self:debug()')
    self:debug()
    print('ok')
end
于 2012-04-28T22:19:35.750 回答