Menu
Coddy logo textTech

メソッドのオーバーライド

CoddyのLuaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 37/70。

これまで、child クラスは親クラスのメソッドを継承し、新しいメソッドを追加してきました。しかし、child が同じ method 名異なる動作を必要とする場合はどうでしょうか?これはmethod のオーバーライドと呼ばれます。

親クラスにある method と同じ名前の method を child class で定義すると、child のバージョンが優先されます。Lua の検索チェーンはまず child class を確認し、そこで method を見つけると検索を停止します。

local Animal = {}
Animal.__index = Animal

function Animal:new(name)
    local obj = {name = name}
    setmetatable(obj, Animal)
    return obj
end

function Animal:speak()
    print(self.name .. " makes a sound")
end

-- Dog が speak() をオーバーライドする
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

function Dog:speak()
    print(self.name .. " barks: Woof!")
end

これで、各クラスは同じメソッド呼び出しに対して異なる応答をします。

local generic = Animal:new("Creature")
local buddy = Dog:new("Buddy")

generic:speak()  -- 出力: Creature が音を出します
buddy:speak()    -- 出力: Buddy が吠えます: Woof!

Dog の :speak() は、Dog インスタンスに対して親のバージョンを完全に置き換えます。これにより、一貫したインターフェースを維持しながら、特化した動作を作成できます。すべての動物が :speak() を実行できますが、それぞれの種で方法が異なります。

challenge icon

チャレンジ

簡単

それぞれ独自の方法で話す、さまざまな生き物が暮らす小さな動物王国を作りましょう!Animal parent classと、親の:speak() methodをそれぞれ独自の動作でオーバーライドする2つの child classes、CatCowを作成します。

コードを4つのファイルに整理します。

  • Animal.lua:動物の名前を保存する:new(name) constructorを持つ Base classです。動物の名前の後にmakes a soundを出力する:speak() methodも含めます。これは child classesがオーバーライドする Defaultの動作です。
  • Cat.lua:Animalからinheritsする child classです。その:new(name) constructorでは、parent constructorを呼び出した後、metatableをCatに再リンクします。:speak() methodをオーバーライドし、catsが別の内容を言うようにします。catの名前の後にmeows: Meow!を出力してください。
  • Cow.lua:Animalからinheritsするもう1つの child classです。constructorはCatと同じ方法で設定します。:speak()をオーバーライドし、cowsの名前の後にmoos: Moo!を出力します。
  • main.lua:everythingをまとめます!inputから2つの名前を読み取り、firstの名前でCatを、secondの名前でCowをCreateし、その後それぞれに:speak()をCallして、同じmethod名でもclassによって異なる出力になることを示します。

2つのinputを受け取ります。

  1. catの名前
  2. cowの名前

mainファイルで両方の動物を作成し、最初にcat、followed by cowの順で:speak()をCallします。

たとえば、inputがWhiskersBessieの場合、出力は次のようになります。

Whiskers meows: Meow!
Bessie moos: Moo!

どちらの動物も同じ:speak() methodの呼び出しに応答しますが、それぞれ自分のtypeに固有の出力を生成することに注目してください。Catのバージョンは、parentの genericな "makes a sound"動作を完全に置き換え、Cowのバージョンも同様です。これが実際のmethod overridingです。同じinterface、異なるimplementationsです。

自分で試してみよう

-- main.lua: すべてをまとめる

local Cat = require('Cat')
local Cow = require('Cow')

-- 入力を読み取る
local catName = io.read()
local cowName = io.read()

-- TODO: 最初の名前で Cat を作成する

-- TODO: 2番目の名前で Cow を作成する

-- TODO: まず cat に対して :speak() を呼び出し、次に cow に対して呼び出す
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Luaオンラインコンパイラ