Luaでオブジェクト指向プログラミングをする方法
Luaでオブジェクト指向プログラミングをする場合は通常 metatable を使った実装となりますが、
Playdate SDKでは "CoreLibs/object" というライブラリが提供されており、Luaで手軽にオブジェクト指向プログラミング(OOP)を行うことができます。
このページでは "CoreLibs/object" を使用したクラスの定義、継承、インスタンス化の記述方法をまとめます。
基本的な使い方
| 項目 |
記述例 |
| import文 |
import "CoreLibs/object" |
| クラス定義 |
class('Name').extends(Parent) |
| 初期化 |
function Name:init(...) |
| メソッド定義 |
function Name:methodName(...) (コロンを使う) |
| 親の呼び出し |
Name.super.methodName(self, ...) (ドットとselfを使う) |
| 生成 (インスタンス化) |
local obj = Name(...) |
1. ライブラリのインポート
まず、スクリプトの先頭でライブラリをインポートします。
2. クラスの定義とコンストラクタ
class('クラス名').extends()を使用してクラスを定義します。初期化処理(コンストラクタ)は init メソッド内に記述します。
(※Luaの文法上、シングルクォートとダブルクォートのどちらでも問題ないですが、Playdate SDKの記述に合わせて、ここではシングルクォートでクラス定義を行います)
注意:
class('ClassName') を実行すると、ClassName という名前のグローバル変数としてクラスが登録されます。
-- MyClassというクラスを定義(デフォルトでObjectクラスを継承します)
class('MyClass').extends()
-- コンストラクタ(インスタンス生成時に自動で呼ばれる)
function MyClass:init(x, y)
self.x = x
self.y = y
end
-- メソッドの定義(必ずコロン ':' を使って定義します)
function MyClass:printPosition()
print("Position: " .. self.x .. ", " .. self.y)
end
3. インスタンス化
クラス名を関数のように呼び出すことで、新しいインスタンスを生成できます。このとき渡した引数は、そのまま init メソッドに渡されます。
-- インスタンスの生成(newなどのキーワードは不要です)
local myObject = MyClass(10, 20)
-- メソッドの呼び出し
myObject:printPosition() -- 出力: Position: 10, 20
4. 継承 (Inheritance)
既存のクラスを継承して新しいクラスを作る場合は、`.extends()` の引数に親クラスを指定します。Playdate開発では、`playdate.graphics.sprite` を継承してカスタムスプライトを作ることが最も多いユースケースです。
-- MyClassを継承したPlayerクラスを定義
class('Player').extends(MyClass)
function Player:init(x, y, name)
-- 親クラスのコンストラクタを呼び出す(必須)
Player.super.init(self, x, y)
self.name = name
self.hp = 100
end
function Player:printStatus()
print(self.name .. " (HP: " .. self.hp .. ")")
self:printPosition() -- 親クラスのメソッドも使用可能
end
- 親メソッドの呼び出し: クラス名.super.メソッド名(self, 引数) という構文を使います。コロン ":" ではなくドット "." と "self" を明示的に渡す必要がある点に注意してください。
5. Playdate特有の実践的な例(Spriteの継承)
import "CoreLibs/object"
import "CoreLibs/graphics"
import "CoreLibs/sprites"
local gfx = playdate.graphics
-- スプライトを継承
class('Enemy').extends(gfx.sprite)
function Enemy:init(x, y)
-- 親クラス(sprite)のinitを呼ぶ
Enemy.super.init(self)
-- スプライトの初期設定
local image = gfx.image.new(32, 32, gfx.kColorBlack)
self:setImage(image)
self:moveTo(x, y)
self:add() -- 画面の描画リストに追加
end
-- 毎フレーム呼ばれる更新処理をオーバーライド
function Enemy:update()
self:moveBy(1, 0) -- 右へ移動
end
その他のTips
カプセル化(private変数・private関数)の実装方法
Luaでは、
オブジェクト指向に対応している言語ではないため、アクセス指定子を指定してカプセル化することはできません。
そのため、変数や関数名の先頭に「_」をつけるなどして運用で対処するのがベターです。
なおクロージャーを使って完全に隠蔽することはできますが、インスタンスごとに関数が作られてしまって
メモリを圧迫する可能性があるので、シングルトンでない限りクロージャーで隠蔽するのは避けた方が良さそうです。
関連ページ
最終更新:2026年04月27日 07:20