Menu
Coddy logo textTech

独立したインスタンス

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 は独自のデータを持ち、独自の生活を送ります。

challenge icon

チャレンジ

簡単

同じ class のオブジェクトが本当に独立して動作することを証明しましょう!Wallet class を構築し、2つの separate な wallet instance を作成してから、それぞれを独立して変更し、一方への変更がもう一方に影響しないことを示します。

コードを2つのファイルに分けて整理します。

  • Wallet.lua:標準的なコンストラクターのパターンを使用してWallet class を Define します。各 wallet は自身のbalanceを追跡します。以下を含めてください。
    • 指定された amount で wallet を初期化する:new(startingBalance)コンストラクター
    • balance を増加させる:add(amount) method
    • balance を減少させる:spend(amount) method
  • main.lua:Wallet module を Require し、2つの separate な wallet instance を作成します。それぞれに異なる操作を行い、独立した state を維持することを示します。

4つの inputs が与えられます。

  1. wallet A の starting balance
  2. wallet B の starting balance
  3. wallet A に Add する amount
  4. wallet B から Spend する amount

main file では、次の操作を行います。

  1. 最初の starting balance でwalletAを Create する
  2. 2番目の starting balance でwalletBを Create する
  3. 指定された amount をwalletAに Add する
  4. 指定された amount をwalletBから Spend する
  5. 両方の balance を separate な行に Print する

最終的な balance を次の exact な format で Print します。

Wallet A: [balance]
Wallet B: [balance]

たとえば、inputs が100502510の場合、Output は次のようになります。

Wallet A: 125
Wallet B: 40

wallet 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]"
quiz icon腕試し

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

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

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