投稿

5月, 2015の投稿を表示しています

Luaでオブジェクト指向(再考)・・・継承について

前回の方法 では、 selfにすべてメソッドを持ってしまう ので、メモリ食い過ぎますね。 そこで、もうちょっと世の中の人に聞いてみると、 Minecraftとタートルと僕 さんがさらにいい方法を紹介してくれていました。 つまり、 クラスのテーブル本体にメソッド定義 を書いて、 インスタンスは metatable の __index 経由で参照させる という方法です。これならば、余分なメモリを食いませんね。すばらしい・・・ でも、継承については書かれていませんでしたので、いろいろ考えてみた結果こんなふうに書いていくことになりましたとさ・・・ついでに、私好みに見通しがいいコードを目指しました。 結局superを使うことは出来ず、クラス名で親クラスを指定してメソッドを呼び出す形に落ち着きました。 構造の見通しがよいように、インスタンスを作る関数instance()を定義します。 function instance(class, super, ...) local self = (super and super.new(...) or {}) setmetatable (self, {__index = class}) setmetatable (class, {__index = super}) return self end この継承の仕組みはインスタンスもクラスを継承していると言えますな。 なので、インスタンスと親クラス、それぞれが継承するように metatabelの__indexに書いてあげる必要があるのです。 この関数の使い方は、自クラス名、親クラス名、引数を順に指定します。 これで、継承されたインスタンスを取得できるというわけです。 また、Luaは引数の省略ができるので、親クラスがない場合は引数を書かないという形で利用します。 ちなみに、... は可変引数のテーブル変数名ですな。これが、擬似コードじゃなくて本物であるところがおもしろい。 で、クラス定義はこんな感じ -- クラス定義 Human = { -- コンストラクタ new = function (name, age, sex) local self = instance( H