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はタブ順にクラスをロードするため、スーパークラスのタブはサブクラスのタブよりも前にある必要があることに注意してください。Codeaフォーラムでこのスレッドを確認することをお勧めします。以下の手法について説明し、基礎となるメカニズムについての洞察も提供します。

まず、コンストラクターが(x、y)座標を取るスーパークラスAbstractSpriteを定義します。この座標をコンソールにエコーするためのメソッドデバッグを提供します。

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と「raw」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

免責事項:私はLuaのオブジェクト指向プログラミングである中産階級の作者です。

最初の例で指摘したクロージャベースの演習は、優れた知的演習ですが、実用的な価値はほとんどありません。Luaでは、オブジェクト指向はテーブルを使用するとより適切に実現されます(2番目の例で指摘されている例が示すように)。これにより、同等の機能がより高速に提供されます。唯一の違いは構文です。

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 に答える