Независимые экземпляры
Часть раздела Объектно-ориентированное программирование путешествия по Lua на Coddy. Урок 10 из 70.
Важный аспект объектно-ориентированного программирования заключается в том, что каждый instance сохраняет своё отдельное separate состояние. Когда вы create два объекта из одного и того же class, они полностью независимы: изменение одного не влияет на другой.
Рассмотрим этот пример:
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, хранящееся в его собственной таблице экземпляра.
Эта независимость и делает объекты полезными. Ты можешь создать десятки игроков в игре, каждый из которых отслеживает собственные здоровье и счёт. Ты можешь управлять несколькими банковскими счетами, у каждого из которых свой баланс.
Класс определяет структуру и поведение, но каждый instance живёт своей собственной жизнью со своими данными.
Задание
ЛегкоДавайте докажем, что объекты одного и того же class действительно живут независимой жизнью! Вы создадите class Wallet и два separate экземпляра кошелька, а затем независимо измените их, чтобы продемонстрировать, что изменения одного не влияют на другой.
Вы организуете свой код в двух файлах:
Wallet.lua: Define ваш classWalletсо стандартным шаблоном конструктора. Каждый кошелёк должен отслеживать собственныйbalance. Включите:- конструктор
:new(startingBalance), который инициализирует кошелёк заданной суммой - метод
:add(amount), который увеличивает balance - метод
:spend(amount), который уменьшает balance
- конструктор
main.lua: подключите свой модуль Wallet и создайте два separate экземпляра кошелька. Выполните разные операции над каждым, чтобы показать, что они сохраняют независимое состояние.
Вы получите четыре входных значения:
- Starting balance для кошелька A
- Starting balance для кошелька B
- Сумма для добавления к кошельку A
- Сумма для траты из кошелька B
В вашем основном файле:
- Создайте
walletAс первым starting balance - Создайте
walletBсо вторым starting balance - Добавьте specified сумму к
walletA - Потратьте specified сумму из
walletB - Выведите оба баланса в отдельных строках
Выведите итоговые балансы в точно таком формате:
Wallet A: [balance]
Wallet B: [balance]Например, если входные значения равны 100, 50, 25 и 10, вывод должен быть таким:
Wallet A: 125
Wallet B: 40Обратите внимание: добавление средств в кошелёк A не изменяет кошелёк B, а трата средств из кошелька B не влияет на кошелёк A: каждый экземпляр хранит свой отдельный 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: Создать walletB со вторым начальным балансом
-- TODO: Добавить указанную сумму в walletA
-- TODO: Потратить указанную сумму из walletB
-- TODO: Вывести итоговые балансы в требуемом формате
-- Формат: "Wallet A: [balance]" и "Wallet B: [balance]"
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Концепция 'self'
Таблицы с функциямиЯвный 'self'Синтаксис с двоеточиемТочка против двоеточияИтоги — Движущаяся точка4Проект: Цифровой банк
Настройка проектаМетод пополнения7Полиморфизм и переопределение
Переопределение методовВызов родительских методовУтиная типизацияОбщий интерфейсПроверка типаИтоги — Роли сотрудников2Паттерн прототипа класса
Концепция прототипаСвязывание через __indexКонструктор :new()Инициализация атрибутовНезависимые экземплярыИтоги — Автозавод5Перегрузка операторов в ООП
Сложение объектовВычитание объектовКонкатенация объектовСравнение объектов (<, >)Повторение — Математика кошелька8Инкапсуляция
Соглашения об именованииЗамыкания для приватностиДоступ через замыканияТаблицы только для чтенияЛогика валидацииИтоги — Защищенное хранилище11Паттерны проектирования (Lite)
Фабричные функцииТаблица SingletonПаттерн IteratorObserver (Слушатель)Итоги — Logger Factory3Состояние и поведение объектов
Переменные экземпляраГеттерыСеттерыВычисляемые свойстваФорматирование строкПроверка на равенствоПовторение — Оценка студента6Основы наследования
Настройка наследованияНаследование методовРасширение конструктораДобавление дочерних методовОбщее и уникальноеИтоги: Иерархия фигурПотренируйтесь самостоятельно: Онлайн-компилятор Lua