🖥️

【Roblox】 メタテーブルを用いたオブジェクト指向プログラミング

2024/08/30に公開

はじめに

今回はメタテーブルを用いたオブジェクト指向プログラミングの実装についてまとめようと思います。
なおメタテーブルの細かな基礎部分は言及していません。

Robloxバージョン:0.638.1.6380615

参考にした記事・サイト
https://create.roblox.com/docs/luau/metatables#using-the-set-datatype
https://devforum.roblox.com/t/what-does-tableindex-table-do/667043/2

クラスの実装

今回はModuleScriptを用いてクラスを実装してみます。

▼ クラス(ModuleScript)

local Character = {}
Character.__index = Character

-- コンストラクタ(クラス作成)
function Character.new(name, health)
	local self = setmetatable({}, Character)
	self.name = name
	self.health = health
	return self
end

-- 攻撃
function Character:Attack()
    print(self.name.." Attack!!")
end

return Character

▼ クラスの作成、利用

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CharacterClass = require(ReplicatedStorage:WaitForChild("Character"))

local enemy = CharacterClass.new("enemy1", 100)

enemy:Attack()

__indexはテーブルで存在しないキーにアクセスしようとしたときに、そのキーを探す先を指定するためのメタメソッドです。ここでは Character 自身を指しているので、メソッド呼び出しなどで Character テーブルが参照されます。

Character.new()でクラスを作成しています。
テーブルを作成しCharacterテーブルをメタテーブルとして設定することで
Characterのメソッドを利用できます。

継承、オーバーライド

さらにメタテーブルを利用することで、先ほど作成したクラスを継承したクラスを作成することもできます。

▼ ボスクラス(ModuleScript)

-- 継承元となるキャラクタークラス
local BaseClass = require(script.Parent:WaitForChild("Character"))

local Boss = {}
Boss.__index = Boss

-- Bossのメタテーブルを設定
setmetatable(Boss, {__index = BaseClass})

-- コンストラクタ(キャラクタークラスを継承)
function Boss.new(name, health)
	local self = BaseClass.new(name, health)
	setmetatable(self, Boss)
	return self
end

-- 攻撃処理
-- 基底クラスにも同じメソッドがあるのでオーバーライドになる
function Boss:Attack()

    -- 基底クラスのメソッドを呼び出す場合はselfを渡す。
    BaseClass.Attack(self)

    print(self.name.."Boss Attack !!")
end

return Boss

BossテーブルのメタテーブルにCharacterクラスを設定することで、
Bossクラスで存在しないメソッドやプロパティにアクセスするとき、BaseClass が参照されます。

クラスを作成する際は、Characterクラスを作成しこれをメタテーブルとしたBossクラスを作成しています。

Bossクラスに存在するAttackメソッドはCharacterクラスのAttackメソッドをオーバーライドしたメソッドとして実行されます。
この際、CharacterクラスのAttackメソッドを呼び出したい場合は引数にselfを渡します。

▼ BossクラスのAttackメソッド

function Boss:Attack()
    -- .メソッドを指定して、selfを渡す。
    BaseClass.Attack(self)

    print(self.name.."Boss Attack !!")
end

スタック、キューの作成

上記のクラスの知識を使用して、スタック、キューのクラスを作成することもできます。
詳しくは公式のリファレンスから確認できるのでぜひ参考にしてみてください!
https://create.roblox.com/docs/luau/stacks
https://create.roblox.com/docs/luau/queues

まとめ

  • メタテーブルを設定することで、テーブルをクラスのように扱うことができる。

  • さらに継承やオーバーライドも可能。

  • スタックやキューはメタテーブルを使用して作成する。

メタテーブルを使用することでコードの可読性が損なわれる可能性もあります。
ただ個人的には便利なテーブルをさらに強化するのに役立つと思います。
是非メタテーブルを使ってみましょう!

ランド・ホー Roblox開発チーム

Discussion