独立したインスタンス
CoddyのLuaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 10/70。
オブジェクト指向プログラミングの重要な側面は、各インスタンスが独自の状態を保持することです。同じクラスから2つのオブジェクトを作成すると、それらは完全に独立しています。一方を変更しても、もう一方には影響しません。
この例を考えてみましょう:
local Counter = {}
Counter.__index = Counter
function Counter:new(start)
local instance = {}
setmetatable(instance, self)
instance.value = start or 0
return instance
end
function Counter:increment()
self.value = self.value + 1
end
-- 2つの別々のカウンターを作成する
local counterA = Counter:new(10)
local counterB = Counter:new(5)
counterA:increment()
counterA:increment()
print(counterA.value) -- 出力: 12
print(counterB.value) -- 出力: 5両方のカウンターは同じ Counter クラスから作成されていますが、counterA をインクリメントしても counterB には影響しません。各オブジェクトには、それぞれのインスタンステーブルに保存された独自の value フィールドがあります。
この独立性こそが、オブジェクトを便利なものにします。ゲーム内に何十人ものプレイヤーを作成し、それぞれの体力とスコアを追跡できます。複数の銀行口座を管理でき、それぞれ異なる残高を持たせられます。
class は構造と振る舞いを定義しますが、それぞれの instance は独自のデータを持ち、独自の生活を送ります。
チャレンジ
簡単同じ class のオブジェクトが本当に独立して動作することを証明しましょう!Wallet class を構築し、2つの separate な wallet instance を作成してから、それぞれを独立して変更し、一方への変更がもう一方に影響しないことを示します。
コードを2つのファイルに分けて整理します。
Wallet.lua:標準的なコンストラクターのパターンを使用してWalletclass を Define します。各 wallet は自身のbalanceを追跡します。以下を含めてください。- 指定された amount で wallet を初期化する
:new(startingBalance)コンストラクター - balance を増加させる
:add(amount)method - balance を減少させる
:spend(amount)method
- 指定された amount で wallet を初期化する
main.lua:Wallet module を Require し、2つの separate な wallet instance を作成します。それぞれに異なる操作を行い、独立した state を維持することを示します。
4つの inputs が与えられます。
- wallet A の starting balance
- wallet B の starting balance
- wallet A に Add する amount
- wallet B から Spend する amount
main file では、次の操作を行います。
- 最初の starting balance で
walletAを Create する - 2番目の starting balance で
walletBを Create する - 指定された amount を
walletAに Add する - 指定された amount を
walletBから Spend する - 両方の balance を separate な行に Print する
最終的な balance を次の exact な format で Print します。
Wallet A: [balance]
Wallet B: [balance]たとえば、inputs が100、50、25、10の場合、Output は次のようになります。
Wallet A: 125
Wallet B: 40wallet A に Add しても wallet B は変わらず、wallet B から Spend しても wallet A には影響しないことに注目してください。それぞれの instance が自身の separate な balance を維持しています。
自分で試してみよう
-- Walletモジュールを読み込む
local Wallet = require('Wallet')
-- 入力を読み取る
local startingA = tonumber(io.read())
local startingB = tonumber(io.read())
local addAmount = tonumber(io.read())
local spendAmount = tonumber(io.read())
-- TODO: 最初の開始残高でwalletAを作成する
-- TODO: 2番目の開始残高でwalletBを作成する
-- TODO: 指定された金額をwalletAに追加する
-- TODO: 指定された金額をwalletBから使う
-- TODO: 必要な形式で最終残高を出力する
-- 形式: "Wallet A: [balance]" および "Wallet B: [balance]"
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Luaオンラインコンパイラ