プログラミングの魔物

エラー、バグ、仕様変更と戦うブログ

Luaのオブジェクト指向プログラミング考察4

Luaポリモーフィズム
オブジェクト指向シリーズということで多様性についての考察。

--クラス定義
a = {f = function (self) print("aのメソッド") end}
b = {f = function (self) print("bのメソッド") end}


--o:f()  --> 初期化前に呼ぶとエラー

--汎用ヌルオブジェクト
null = setmetatable({}, {__index = function () return function() end end})


o = null
o:f()  -- !何もしない!

o = a
o:f()  --> aのメソッド

o = b
o:f()  --> bのメソッド

Luaのクラスはテーブルなので、oの中身を気にすること無くf()を呼ぶ。
初期化前にo:f()を呼び出すとエラーになるので、上記のプログラムでは汎用ヌルオブジェクトnullで初期化している。
nullは要素が参照された時に無名関数を返すだけのものなので、プロパティの参照には対応していない。



追記;
条件を追加することでヌルオブジェクトを使わず、かつ安全にメソッドを実行することも可能だが、ポリモーフィズムを使用する場面では条件分岐を排除することによって見通しを良くする意図がある。
そのため、参照している要素が空であることを示す時にヌルオブジェクトを使用した方が、処理部分はシンプルなコードになる。

objects = {a, b, a, a}

--ゴチャゴチャ
for i, o in ipairs(objects) do
	if type(o) == "table" and type(o.f) == "function" then
		o:f()
	end
end

--シンプル(oの中身はヌルオブジェクトかf()メソッドを実装しているクラスのみという前提)
for i, o in ipairs(objects) do
	o:f()
end