子クラスのメソッドの追加
CoddyのLuaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 34/70。
継承によって子クラスは親のメソッドにアクセスできますが、本当の力は、子だけが持つ新しいメソッドを追加できることにあります。DogはAnimalにできることをすべてできるだけでなく、吠えることなど、犬特有のこともできます。
child 専用の method の追加は簡単です。child class table 上で定義するだけです。instance はまず自分自身の class で method を検索するため、parent に影響を与えることなく新しい method を見つけられます。
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print(self.name .. " is breathing")
end
-- Dog は Animal を継承する
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new(name)
local obj = Animal.new(Animal, name)
setmetatable(obj, Dog)
return obj
end
-- Dog のみの新しいメソッド
function Dog:bark()
print(self.name .. " says: Woof!")
endこれでDogのインスタンスは、継承されたメソッドと固有のメソッドの両方を使用できます。
local buddy = Dog:new("Buddy")
buddy:breathe() -- 出力: Buddy is breathing (inherited)
buddy:bark() -- 出力: Buddy says: Woof! (child-only)parent class は変更されません。単純な Animal に対して :bark() を呼び出すと、その method はそこに存在しないため失敗します。これが、共有機能を1か所に保持しながら、inheritance によって動作を特殊化できる仕組みです。
チャレンジ
簡単猫が独自の特別な能力を持つペットの階層を作ってみましょう!Pet 親クラスと Cat 子クラスを作成します。Cat は Pet からすべてを継承し、さらに猫だけが実行できる独自のメソッドを持ちます。
コードを3つのファイルに分けて整理します。
Pet.lua:ペットの名前を保存する:new(name)コンストラクターを持つ親クラスを定義します。ペットの名前に続けてsays helloを出力する:greet()メソッドを含めます。標準的なクラスパターンを設定し、クラスを返します。Cat.lua:Pet を継承する子クラスを定義します。Cat の:new(name)コンストラクターでは、親コンストラクターを呼び出して名前を初期化し、その後メタテーブルを Cat に再関連付けします。猫の名前に続けてpurrs contentedlyを出力する、子クラス固有の:purr()メソッドを追加します。このメソッドは Cat にのみ存在します。Pet にはありません。main.lua:Cat モジュールを Require し、入力から名前を読み取り、Cat インスタンスを作成します。そして、継承した:greet()メソッドと、独自の:purr()メソッドの両方を使えることを示します。
入力は1つ、猫の名前です。
メインファイルで、指定された名前を使って Cat を作成し、その後 :greet()、続けて :purr() をそれぞれ別の行で呼び出します。
たとえば、入力が Whiskers の場合、出力は次のようになります。
Whiskers says hello
Whiskers purrs contentedly1行目は Pet で定義された継承された :greet() メソッドから出力され、2行目は Cat にのみ存在する :purr() メソッドから出力されます。これは、子クラスが親クラスにできることをすべて実行でき、さらに独自の特化した動作も追加できることを示しています。
自分で試してみよう
-- main.lua: Catを作成し、継承を示す
local Cat = require('Cat')
-- 入力から猫の名前を読み取る
local name = io.read()
-- TODO: 指定された名前でCatインスタンスを作成する
-- TODO: 継承された :greet() メソッドを呼び出す(Petから)
-- TODO: Cat固有の :purr() メソッドを呼び出す
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Luaオンラインコンパイラ