继承能在Codea中使用吗?

Codea 中可以使用继承吗?虽然我对 Lua 还比较新,但是从一些快速的搜索结果来看,实现 继承和多态 的方法比较 " 复杂"。是否有任何技术可以在 Codea 的 Lua-hosting 引擎下安全地使用?

以下是我正在尝试让其运行的简单可运行测试。我的超类:

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)
    -- 可以在这里接受和设置参数
    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 上可行的技巧。

原文链接 https://stackoverflow.com/questions/10367360

点赞
stackoverflow用户312586
stackoverflow用户312586

免责声明:我是 middleclass 的作者,这是一个用于 Lua 的面向对象库。

你在第一个示例中指出的基于闭包的写法是一种不错的思维练习,但它的实用价值很小。在 Lua 中,使用表更容易实现面向对象(正如你第二个示例所指出的),它具有更高的运行速度,只有不同的语法。

有很多库使用了标准的表驱动方式来实现 Lua 的面向对象编程。你可以在这里找到一个列表:

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

使用 middleclass 库,你的代码将变成这样:

require 'middleclass'

-- middleclass 需要类名作为参数
SuperClass = class('SuperClass') -- 我不明白为什么要用 K,BTW

function SuperClass:initialize(x,y) -- init 改为 initialize
    self.x = x
    self.y = y
end

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

Ship = class('Ship', SuperClass) -- 注意这里我们将超类放在这里

function Ship:initialize(x, y) -- 再次改为 initialize
    -- 你可以在这里接受和设置参数
    print('ship:initialize() called')

    self = SuperClass.initialize(self,x,y) -- 注意这里的额外 self 和 initialize
    print('attempting to call self:debug()')
    self:debug() -- 成功!输出
    print('ok!')
end

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

    print('attempting to call self:debug()')
    self:debug()
    print('ok')
end
2012-04-28 22:19:35
stackoverflow用户90042
stackoverflow用户90042

为了提供一个Codea中类继承的工作解决方案,并指出一些陷阱。首先,我应该指出Codea按tab顺序加载类,因此超类的标签必须在子类的标签之前。我建议看一下Codea论坛上的这个主题。它讨论了下面的技术,并且给出了关于底层机制的一些见解。

首先,我们定义一个超类_AbstractSprite_,它的构造函数采用(x,y)坐标。它提供了一个方法debug来将这个坐标输出到控制台。

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_,它实现了自定义的debug调用_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-29 20:32:06