Menu
Coddy logo textTech

Независимые экземпляры

Часть раздела Object Oriented Programming путешествия по Lua на Coddy — урок 10 из 70.

Важным аспектом объектно-ориентированного программирования является то, что каждый экземпляр сохраняет свое собственное отдельное состояние. Когда вы создаете два объекта одного и того же класса, они полностью независимы — изменение одного не влияет на другой.

Рассмотрим этот пример:

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

-- Создаем два отдельных счетчика
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, хранящееся в его собственной таблице экземпляра.

Эта независимость — то, что делает объекты полезными. Вы можете создать десятки игроков в игре, каждый из которых отслеживает свое собственное здоровье и счет. Вы можете управлять несколькими банковскими счетами, каждый из которых имеет свой баланс.

Класс определяет структуру и поведение, но каждый экземпляр живет своей собственной жизнью со своими собственными данными.

challenge icon

Задание

Легко

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

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

  • Wallet.lua: Определите класс Wallet со стандартным паттерном конструктора. Каждый кошелек должен отслеживать свой собственный balance. Включите:
    • Конструктор :new(startingBalance), который инициализирует кошелек с заданной суммой
    • Метод :add(amount), который увеличивает баланс
    • Метод :spend(amount), который уменьшает баланс
  • main.lua: Подключите модуль Wallet и создайте два отдельных экземпляра кошелька. Выполните различные операции над каждым из них, чтобы показать, что они сохраняют независимое состояние.

Вы получите четыре входных значения:

  1. Начальный баланс для кошелька A
  2. Начальный баланс для кошелька B
  3. Сумма для добавления в кошелек A
  4. Сумма для списания из кошелька B

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

  1. Создайте walletA с первым начальным балансом
  2. Создайте walletB со вторым начальным балансом
  3. Добавьте указанную сумму в walletA
  4. Спишите указанную сумму из walletB
  5. Выведите оба баланса на отдельных строках

Выведите итоговые балансы в этом точном формате:

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

Например, если входные данные равны 100, 50, 25 и 10, вывод должен быть следующим:

Wallet A: 125
Wallet B: 40

Обратите внимание, как добавление в кошелек A не меняет кошелек B, а списание из кошелька B не влияет на кошелек A — каждый экземпляр сохраняет свой собственный отдельный баланс.

Шпаргалка

Каждый экземпляр класса поддерживает свое собственное отдельное состояние. Создание нескольких объектов одного и того же класса приводит к появлению полностью независимых экземпляров — изменение одного из них не влияет на другие.

Пример, демонстрирующий независимость экземпляров:

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

-- Создаем два отдельных счетчика
local counterA = Counter:new(10)
local counterB = Counter:new(5)

counterA:increment()
counterA:increment()

print(counterA.value)  -- Вывод: 12
print(counterB.value)  -- Вывод: 5

Каждый объект имеет свою собственную таблицу экземпляра, в которой хранятся его данные. Класс определяет структуру и поведение, но каждый экземпляр сохраняет независимое состояние.

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

-- Подключить модуль 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: Создать walletB со вторым начальным балансом

-- TODO: Добавить указанную сумму в walletA

-- TODO: Потратить указанную сумму из walletB

-- TODO: Вывести итоговые балансы в требуемом формате
-- Формат: "Wallet A: [balance]" и "Wallet B: [balance]"
quiz iconПроверьте себя

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

Все уроки раздела Object Oriented Programming