算出プロパティ
CoddyのLuaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 15/70。
ゲッターとセッターは保存された値へのアクセスを提供しますが、保存されたフィールドとして存在しないデータが必要になることもあります。そのデータは、他の属性から計算する必要があります。これらは計算プロパティと呼ばれます。
長方形を考えてみましょう。その width と height は保存しますが、area はどこにも保存されません。これは、これら2つの値を掛け合わせて計算されます。冗長なデータを保存する代わりに、結果を計算して返すメソッドを作成します。
local Rectangle = {}
Rectangle.__index = Rectangle
function Rectangle:new(width, height)
local instance = {}
setmetatable(instance, self)
instance.width = width
instance.height = height
return instance
end
function Rectangle:getArea()
return self.width * self.height
end:getArea()メソッドは保存された値を返しません。呼び出すたびに面積を新たに計算します。このアプローチには重要な利点があります。幅または高さが変わると、何も更新しなくても面積に新しい寸法が自動的に反映されます。
local box = Rectangle:new(5, 3)
print(box:getArea()) -- 出力: 15
box.width = 10
print(box:getArea()) -- 出力: 30計算プロパティによって、オブジェクトの一貫性を保てます。他のフィールドに依存する値を保存する(そしてそれらが古くなるリスクを負う)のではなく、必要に応じて計算します。このパターンは、周長、平均、書式設定された文字列、または既存の属性から決定できるあらゆる値など、派生データに適用できます。
チャレンジ
簡単オンデマンドで体積を計算する Box class を作成しましょう!体積をフィールドとして保存する代わりに、必要になるたびに box の寸法から計算する calculated property を作成します。
コードを2つのファイルに分けて整理します。
Box.lua:標準的な prototype pattern を使ってBoxclass を定義します。各 box は3つの寸法、width、height、depthを保存します。以下を含めてください。- 3つすべての寸法を保存する
:new(width, height, depth)Constructor - 体積(width × height × depth)を計算して返す
:getVolume()method - 総 surface area を計算して返す
:getSurfaceArea()method
- 3つすべての寸法を保存する
main.lua:Box module を Require し、box instance を作成して、calculated properties が現在の寸法をどのように自動的に反映するかを示します。
box の surface area は次のように計算されます:2 × (width×height + height×depth + width×depth)
box の寸法を表す3つの入力を受け取ります。
- Width
- Height
- Depth
main file で、given dimensions を使って box を作成し、次の2行を Print します。
:getVolume()を使った volume:getSurfaceArea()を使った surface area
たとえば、入力が 3、4、5 の場合、Output は次のようになります。
60
94calculated properties の利点は、常に正確な状態を保てることです。後から box の寸法の1つを変更した場合でも、もう一度 :getVolume() を呼び出せば、手動で更新しなくても正しい新しい値が自動的に返されます。
自分で試してみよう
-- Boxモジュールを読み込む
local Box = require('Box')
-- 入力の寸法を読み取る
local width = tonumber(io.read())
local height = tonumber(io.read())
local depth = tonumber(io.read())
-- TODO: 与えられた寸法でboxインスタンスを作成する
-- TODO: :getVolume()を使って体積を出力する
-- TODO: :getSurfaceArea()を使って表面積を出力する
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Luaオンラインコンパイラ