Сокрытие информации
Часть раздела Объектно-ориентированное программирование путешествия по GDScript на Coddy. Урок 28 из 65.
Сокрытие информации идёт на шаг дальше, чем приватные переменные: код, использующий класс, зависит только от того, что делают его публичные методы, и никогда — от того, как класс хранит свои данные. Поэтому ты можешь изменить способ хранения, не затрагивая этот код.
# inventory.gd
class_name Inventory
extends RefCounted
var _counts: Dictionary = {}
func add(item: String, amount: int) -> void:
_counts[item] = _counts.get(item, 0) + amount
func count(item: String) -> int:
return _counts.get(item, 0)
func remove(item: String, amount: int) -> bool:
if count(item) < amount:
return false
_counts[item] -= amount
return truemain.gd вызывает add(), count() и remove() и никогда не работает напрямую со словарём. Если позже Inventory будет хранить массив слотов вместо этого, изменится только inventory.gd.
Будь осторожен с геттерами, которые возвращают массив или словарь. GDScript передаёт эти значения по ссылке: вызывающий код получает собственный массив объекта, а не копию, и может изменять его, не вызывая методы класса:
# quest_log.gd
var _quests: Array[String] = ["Find the key"]
func get_quests() -> Array[String]:
return _quests# main.gd
var journal := QuestLog.new()
var quests := journal.get_quests()
quests.append("Skip the boss")
print(journal.get_quests()) # ["Find the key", "Skip the boss"]Вместо этого возвращай копию. duplicate() создаёт новый Array с теми же элементами, поэтому изменения в нём не затрагивают объект:
func get_quests() -> Array[String]:
return _quests.duplicate()Для словаря или массива, содержащего другие массивы, используй duplicate(true): этот метод также копирует внутренние массивы и словари.
Задание
ЛегкоНапиши класс Playlist в файле playlist.gd. Он хранит названия песен в приватном массиве _songs, а другой код использует только эти методы:
add(title)добавляет название и возвращаетtrue. Если это название уже есть в плейлисте, метод ничего не меняет и возвращаетfalse.remove(title)удаляет название и возвращаетtrueили возвращаетfalse, если такого названия нет.count()возвращает количество песен.get_titles()возвращает копию названий в том порядке, в котором они были добавлены.
Предоставленный код считывает количество команд, затем по одной команде в каждой строке (add Blue Sky или remove Blue Sky) и выводит результат. В конце он получает массив из get_titles(), добавляет Intruder и меняет порядок элементов на обратный, а затем выводит количество песен и их названия. Эти изменения не должны затрагивать твой плейлист. Для команд add Blue Sky, add Rain и add Blue Sky вывод будет таким:
Added: Blue Sky
Added: Rain
Already in the playlist: Blue Sky
Songs: 2
Blue Sky, RainТвой код нужно поместить в playlist.gd. В main.gd находится предоставленный код ввода и вывода, его нельзя редактировать.
Попробуйте сами
extends Node
func _ready():
# Предоставленный код ввода-вывода: оставьте его без изменений
var playlist := Playlist.new()
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ", true, 1)
var title := parts[1]
if parts[0] == "add":
if playlist.add(title):
print("Added: " + title)
else:
print("Already in the playlist: " + title)
elif playlist.remove(title):
print("Removed: " + title)
else:
print("Not found: " + title)
# Код, который пытается изменить полученный список
var titles := playlist.get_titles()
titles.append("Intruder")
titles.reverse()
print("Songs: %d" % playlist.count())
print(", ".join(playlist.get_titles()))
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово selfМетодыСвойстваКонструктор (_init)Повторение: простой калькулятор4Полиморфизм
Переопределение методов: повторениеУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовПовторение — калькулятор фигур7Сигналы
Что такое сигнал?Объявление и отправкаПодключение к сигналамСигналы с аргументамиПовторение — система здоровья10Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»2Свойства классов
Переменные экземпляра и классаСтатические функцииСеттеры свойствГеттеры свойствПриватность по соглашениюПовторение — менеджер банковского счёта5Инкапсуляция
Открытые и закрытые членыПроверка данных с помощью сеттеровСокрытие информацииСвойства только для чтенияПовторение — система учета студентов8Продвинутые концепции ООП
Композиция и наследованиеВнутренние классыУзлы как компонентыRefCounted и NodeПеречисления в классах11Проект: Управление библиотекой
Обзор проектаКлассы книг и пользователей3Наследование
Основы наследованияКлючевое слово superПереопределение методовЦепочки наследованияПроверка типов с помощью isПовторение — иерархия сотрудников6Специальные методы
Введение в виртуальные методыМетод _to_stringПользовательские итераторыПовторение: пользовательский список9Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн «Одиночка»Паттерн «Фабрика»Паттерн «Наблюдатель»Паттерн «Стратегия»Потренируйтесь самостоятельно: Онлайн-компилятор GDScript