Menu
Coddy logo textTech

インスタンス変数

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

オブジェクトが内部データを管理する方法に焦点を当てた新しい章へようこそ。クラスとインスタンスの作成方法を学びました。次は、各インスタンスがそれぞれ固有の状態を保存し、管理する方法を探っていきましょう。

Instance 変数は、単一のオブジェクトだけに属するフィールドです。メソッドまたはコンストラクター内で self.something に値を割り当てると、そのデータはその特定の instance にのみ保存されます。同じクラスの他のオブジェクトには、それぞれ独立したコピーがあります。

これは、テーブルのような複雑なデータを保存するときに、特に重要になります。各キャラクターが異なるアイテムを持つインベントリシステムを考えてみましょう。

local Inventory = {}
Inventory.__index = Inventory

function Inventory:new()
    local instance = {}
    setmetatable(instance, self)
    instance.items = {}  -- 各インスタンスは独自の空のテーブルを持つ
    return instance
end

function Inventory:addItem(item)
    table.insert(self.items, item)
end

重要な行は instance.items = {} です。コンストラクタ内に新しい空のテーブルを作成することで、すべての inventory オブジェクトがそれぞれ固有の list を受け取ります。代わりに items を class テーブル自体で定義すると、すべてのインスタンスが誤って同じテーブルを共有することになります。1人のキャラクターに剣を追加すると、全員がその剣を持つことになってしまいます!

local bag1 = Inventory:new()
local bag2 = Inventory:new()

bag1:addItem("Sword")
bag2:addItem("Potion")

print(#bag1.items)  -- 出力: 1
print(#bag2.items)  -- 出力: 1

各inventoryは独自のコレクションを保持します。このパターンは、instanceが独立して変化するデータ(リスト、カウンター、またはそのオブジェクト固有の可変状態)を追跡する必要がある場合に適用されます。

challenge icon

チャレンジ

簡単

各カートがそれぞれ独立した商品リストを保持する ShoppingCart システムを構築しましょう。これにより、インスタンス変数がオブジェクト間でデータを分離して保持する仕組みを確認できます。つまり、あるカートに商品を追加しても、別のカートには影響しません!

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

  • ShoppingCart.lua:各インスタンスが独自の products テーブルを持つ ShoppingCart クラスを定義します。次の要素を含めます。
    • 各カートに空の商品のリストを初期化する :new() コンストラクター
    • このカートのリストに商品を追加する :addProduct(productName) メソッド
    • 各商品を別々の行に出力する :listProducts() メソッド
  • main.lua:ShoppingCart モジュールを Require し、2つの独立したカートを作成します。それぞれのカートに異なる商品を追加して、独立した在庫を維持していることを確認します。

4つの入力を受け取ります。

  1. cart A に追加する最初の商品
  2. cart A に追加する2番目の商品
  3. cart B に追加する最初の商品
  4. cart B に追加する2番目の商品

main ファイルでは、次の処理を行います。

  1. 2つのショッピングカート、cartAcartB を作成する
  2. 最初の2つの商品を cartA に追加する
  3. 最後の2つの商品を cartB に追加する
  4. Cart A: を出力してから、cart A の商品を一覧表示する
  5. Cart B: を出力してから、cart B の商品を一覧表示する

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

Cart A:
Apple
Bread
Cart B:
Milk
Eggs

重要なのは、コンストラクター内で products を新しい空のテーブルとして初期化することです。これにより、すべてのカートで1つのテーブルを共有するのではなく、各カートのインスタンスが独自の別々のリストを持つようになります。

自分で試してみよう

-- ShoppingCartモジュールを読み込む
local ShoppingCart = require('ShoppingCart')

-- 入力を読み取る
local product1 = io.read()
local product2 = io.read()
local product3 = io.read()
local product4 = io.read()

-- TODO: 2つのショッピングカート cartA と cartB を作成する

-- TODO: product1 と product2 を cartA に追加する

-- TODO: product3 と product4 を cartB に追加する

-- TODO: "Cart A:" を出力してから cartA の商品を一覧表示する

-- TODO: "Cart B:" を出力してから cartB の商品を一覧表示する
quiz icon腕試し

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

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

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