算出プロパティ
CoddyのLuaジャーニー「Object Oriented Programming」セクションの一部 — レッスン 15/70。
ゲッターとセッターは保存された値へのアクセスを提供しますが、時には保存されたフィールドとして存在しないデータが必要な場合があります。それは他の属性から計算される必要があります。これらは算出プロパティと呼ばれます。
長方形を考えてみましょう。幅と高さを保存しますが、面積はどこにも保存されません。これら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 クラスを作成しましょう!体積をフィールドとして保存する代わりに、必要になるたびにボックスの寸法から計算する「計算されたプロパティ」を作成します。
コードは2つのファイルに分けて構成します:
Box.lua: 標準的なプロトタイプパターンを使用してBoxクラスを定義します。各ボックスはwidth、height、depthの3つの寸法を保持します。以下を含めてください:- 3つの寸法すべてを保存する
:new(width, height, depth)コンストラクタ - 体積(width × height × depth)を計算して返す
:getVolume()メソッド - 全表面積を計算して返す
:getSurfaceArea()メソッド
- 3つの寸法すべてを保存する
main.lua: Box モジュールを読み込み(require)、ボックスのインスタンスを作成し、計算されたプロパティが現在の寸法をどのように自動的に反映するかを示します。
ボックスの表面積は、次の式で計算されます:2 × (width×height + height×depth + width×depth)
ボックスの寸法を表す3つの入力を受け取ります:
- Width(幅)
- Height(高さ)
- Depth(奥行き)
メインファイルで、与えられた寸法でボックスを作成し、次の2行を出力してください:
:getVolume()を使用した体積:getSurfaceArea()を使用した表面積
例えば、入力が 3、4、5 の場合、出力は次のようになります:
60
94計算されたプロパティの利点は、常に正確であることです。後でボックスの寸法のいずれかを変更した場合、再び :getVolume() を呼び出すと、手動で更新することなく自動的に正しい新しい値が返されます!
チートシート
算出プロパティは、値を直接保存するのではなく、他の属性に基づいて値を計算して返すメソッドです。これにより、データの整合性が確保され、冗長性が排除されます。
面積の算出プロパティの例:
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モジュールを読み込む
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()を使用して表面積を出力する
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。