Menu
Coddy logo textTech

Переменные экземпляра

Часть раздела Объектно-ориентированное программирование путешествия по Lua на Coddy. Урок 12 из 70.

Добро пожаловать в новую главу, посвящённую тому, как объекты управляют своими внутренними данными. Вы научились создавать классы и экземпляры: теперь пришло время узнать, как каждый экземпляр хранит своё уникальное состояние и управляет им.

Переменные экземпляра — это поля, которые принадлежат исключительно одному объекту. Когда вы присваиваете значение self.something внутри метода или конструктора, эти данные существуют только в данном экземпляре. У других объектов того же класса есть свои отдельные копии.

Это становится особенно важным при хранении сложных данных, таких как таблицы. Рассмотрим систему инвентаря, в которой каждый персонаж носит разные предметы:

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 отдельный список. Если бы вместо этого ты определил items в самой таблице class, все экземпляры случайно использовали бы одну и ту же таблицу: добавление меча одному персонажу выдало бы его всем!

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

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

print(#bag1.items)  -- Вывод: 1
print(#bag2.items)  -- Вывод: 1

Each inventory поддерживает свою own коллекцию. Этот шаблон применяется всякий раз, когда instance необходимо отслеживать данные, которые изменяются независимо: списки, счётчики или любое изменяемое состояние, уникальное для этого объекта.

challenge icon

Задание

Легко

Создадим систему ShoppingCart, где each cart поддерживает собственный отдельный список products. Это продемонстрирует, как переменные экземпляра изолируют данные между объектами: добавление items в одну cart не повлияет на другую!

Вы организуете код в двух файлах:

  • ShoppingCart.lua: Определите class ShoppingCart, где каждый instance имеет собственную таблицу products. Включите:
    • Конструктор :new(), который инициализирует пустой список products для каждой cart
    • Метод :addProduct(productName), который добавляет product в список этой cart
    • Метод :listProducts(), который выводит каждый product в отдельной строке
  • main.lua: Подключите модуль ShoppingCart и создайте две отдельные cart. Добавьте разные products в каждую cart, чтобы доказать, что они поддерживают независимые inventory.

Вы получите four inputs:

  1. Первый product для добавления в cart A
  2. Второй product для добавления в cart A
  3. Первый product для добавления в cart B
  4. Второй product для добавления в cart B

В вашем основном файле:

  1. Создайте две shopping cart: cartA и cartB
  2. Добавьте первые два products в cartA
  3. Добавьте последние два products в cartB
  4. Выведите Cart A:, затем выведите products cart A
  5. Выведите Cart B:, затем выведите products cart B

Например, если inputs имеют значения Apple, Bread, Milk и Eggs, вывод должен быть таким:

Cart A:
Apple
Bread
Cart B:
Milk
Eggs

Помните: ключевой момент — инициализировать products как новую пустую таблицу внутри конструктора. Это гарантирует, что каждый cart instance получит собственный отдельный список, а не будет использовать одну таблицу совместно со всеми cart.

Попробуйте сами

-- Подключить модуль ShoppingCart
local ShoppingCart = require('ShoppingCart')

-- Прочитать входные данные
local product1 = io.read()
local product2 = io.read()
local product3 = io.read()
local product4 = io.read()

-- TODO: Создать две корзины покупок: cartA и cartB

-- TODO: Добавить product1 и product2 в cartA

-- TODO: Добавить product3 и product4 в cartB

-- TODO: Вывести "Cart A:", затем перечислить продукты cartA

-- TODO: Вывести "Cart B:", затем перечислить продукты cartB
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Lua