最初版は Lua 5.0 に基づいて書かれました。後からのバージョンでも概ね関連していますが、いくつか違いがあります。
第 4 版は Lua 5.3 を対象にしており、Amazon や他の書店で購入できます。
この本を購入することで Lua プロジェクトをサポート することにもなります。
![]() |
プログラミングLua | ![]() |
パート II. テーブルとオブジェクト 第 16 章 オブジェクト指向プログラミング |
クラスはオブジェクトであるため、他のクラスからメソッドを取得することもできます。これにより、(通常のオブジェクト指向の用語での)継承を Lua に実装することが非常に容易になります。
Account
のような基本クラスがあるとします。
Account = {balance = 0} function Account:new (o) o = o or {} setmetatable(o, self) self.__index = self return o end function Account:deposit (v) self.balance = self.balance + v end function Account:withdraw (v) if v > self.balance then error"insufficient funds" end self.balance = self.balance - v end
このクラスから、顧客が自身の残高以上の引き出しを許可する SpecialAccount
というサブクラスを作成することを想定します。基本クラスからすべてのオペレーションを継承する単なる空のクラスから始めましょう
SpecialAccount = Account:new()これまでのところ、
SpecialAccount
は Account
のインスタンスに過ぎません。ここで素晴らしいことが起こりますs = SpecialAccount:new{limit=1000.00}
SpecialAccount
は、他のメソッドと同じように Account
から new
を継承します。しかし、この場合、new
が実行されると、self
パラメータは SpecialAccount
を参照します。したがって、s
のメタテーブルは SpecialAccount
になり、インデックス __index
の値も SpecialAccount
になります。つまり、s
は Account
から継承する SpecialAccount
から継承します。次のように評価するとs:deposit(100.00)Lua は
s
に deposit
フィールドがないので SpecialAccount
を検索します。ここにも deposit
フィールドが見つからないので、Account
を検索し、そこでデポジットのオリジナル実装を見つけます。SpecialAccount
を特別なものにする点は、スーパークラスから継承したすべてのメソッドを再定義できることです。新しいメソッドを書くだけです
function SpecialAccount:withdraw (v) if v - self.balance >= self:getLimit() then error"insufficient funds" end self.balance = self.balance - v end function SpecialAccount:getLimit () return self.limit or 0 endこれで、
s:withdraw(200.00)
を呼び出すと、Lua は新しい withdraw
メソッドを最初に SpecialAccount
で見つけるので Account
にはアクセスしません。s.limit
は 1000.00(s
の作成時にこのフィールドを設定したことを思い出してください)であるため、プログラムは引き出しを行い、s
は残高をマイナスにします。Lua の OO の興味深い点は、新しい動作を指定するために新しいクラスを作成する必要がないことです。単一のオブジェクトに特定の動作が必要な場合は、その動作をオブジェクトに直接実装できます。たとえば、アカウント s
が常に残高の 10% である金額の引き出しを許可する特別なクライアントの場合は、この単一のアカウントだけを変更できます
function s:getLimit () return self.balance * 0.10 endこの宣言後、
s:withdraw(200.00)
の呼び出しは SpecialAccount
から withdraw
メソッドを実行しますが、そのメソッドが self:getLimit
を呼び出すと、最後に呼び出されるのはこの定義です。Copyright © 2003–2004 Roberto Ierusalimschy. All rights reserved. | ![]() |