Соглашения об именовании
Часть раздела Объектно-ориентированное программирование путешествия по Lua на Coddy — урок 43 из 70.
В Lua все поля таблиц по умолчанию являются общедоступными. Любой может прочитать или изменить self.health напрямую. Хотя Lua не обеспечивает приватность принудительно, программисты используют соглашения об именовании для передачи намерений — указывая, какие поля следует рассматривать как детали внутренней реализации.
Стандартное соглашение заключается в том, чтобы добавлять префикс в виде нижнего подчеркивания к приватным полям:
local Player = {}
Player.__index = Player
function Player:new(name)
local obj = {
name = name, -- Публичное: можно обращаться напрямую
_health = 100, -- Приватное: используйте методы вместо этого
_score = 0 -- Приватное: внутреннее отслеживание
}
setmetatable(obj, Player)
return obj
end
function Player:getHealth()
return self._health
end
function Player:takeDamage(amount)
self._health = self._health - amount
endНижнее подчеркивание не меняет принцип работы Lua — player._health все еще технически доступно. Тем не менее, оно служит четким предупреждением для других программистов (и для вас в будущем): «Это поле предназначено для внутреннего использования. Вместо этого обращайтесь к нему через методы».
Это соглашение важно, потому что оно отделяет интерфейс (то, что должны использовать другие) от реализации (того, как это работает внутри). Если позже вам понадобится добавить валидацию или изменить способ хранения здоровья, вы измените только методы — код, использующий :getHealth(), продолжит работать без изменений.
Задание
ЛегкоДавайте создадим класс BankAccount, который правильно сигнализирует о том, какие поля должны быть приватными, используя соглашение об именовании с подчеркиванием!
Вы организуете свой код в двух файлах:
BankAccount.lua: Создайте класс, который управляет информацией о счете. Конструктор:new(ownerName, initialBalance)должен сохранять имя владельца как публичное поле (owner), а баланс — как приватное поле (_balance). Включите три метода::getBalance()— возвращает текущий баланс:deposit(amount)— добавляет сумму к_balance:getOwner()— возвращает имя владельца
main.lua: Подключите модуль BankAccount, считайте имя владельца, начальный баланс и сумму депозита из входных данных. Создайте счет, внесите депозит, а затем выведите имя владельца и итоговый баланс.
Вы получите три входных значения:
- Имя владельца
- Начальный баланс (число)
- Сумма депозита (число)
Ваш вывод должен состоять из двух строк, показывающих владельца и итоговый баланс после депозита:
Owner: {ownerName}
Balance: {finalBalance}Например, если входные данные — Maria, 500 и 150, вывод должен быть следующим:
Owner: Maria
Balance: 650Помните: префикс в виде подчеркивания в _balance сигнализирует другим программистам, что к этому полю следует обращаться через такие методы, как :getBalance() и :deposit(), а не напрямую. Поле owner без подчеркивания указывает на то, что к нему можно обращаться публично.
Попробуйте сами
-- Подключить модуль BankAccount
local BankAccount = require('BankAccount')
-- Прочитать входные данные
local ownerName = io.read()
local initialBalance = tonumber(io.read())
local depositAmount = tonumber(io.read())
-- TODO: Создать новый BankAccount с ownerName и initialBalance
-- TODO: Внести депозит, используя depositAmount
-- TODO: Вывести владельца и итоговый баланс в требуемом формате
-- Формат:
-- Owner: {ownerName}
-- Balance: {finalBalance}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Концепция 'self'
Таблицы с функциямиЯвный 'self'Синтаксис с двоеточиемТочка против двоеточияИтоги — Движущаяся точка4Проект: Цифровой банк
Настройка проектаМетод пополнения7Полиморфизм и переопределение
Переопределение методовВызов родительских методовУтиная типизацияОбщий интерфейсПроверка типаИтоги — Роли сотрудников2Паттерн прототипа класса
Концепция прототипаСвязывание через __indexКонструктор :new()Инициализация атрибутовНезависимые экземплярыИтоги — Автозавод5Перегрузка операторов в ООП
Сложение объектовВычитание объектовКонкатенация объектовСравнение объектов (<, >)Повторение — Математика кошелька8Инкапсуляция
Соглашения об именованииЗамыкания для приватностиДоступ через замыканияТаблицы только для чтенияЛогика валидацииИтоги — Защищенное хранилище11Паттерны проектирования (Lite)
Фабричные функцииТаблица SingletonПаттерн IteratorObserver (Слушатель)Итоги — Logger Factory3Состояние и поведение объектов
Переменные экземпляраГеттерыСеттерыВычисляемые свойстваФорматирование строкПроверка на равенствоПовторение — Оценка студента6Основы наследования
Настройка наследованияНаследование методовРасширение конструктораДобавление дочерних методовОбщее и уникальноеИтоги: Иерархия фигур