Открытые и закрытые члены
Часть раздела Объектно-ориентированное программирование путешествия по GDScript на Coddy. Урок 26 из 65.
Инкапсуляция означает, что объект хранит свои данные вместе с методами, которые изменяют эти данные, и определяет, какие его члены может использовать другой код. Члены, предназначенные для другого кода, образуют интерфейс объекта.
В GDScript нет ключевых слов public или private: к каждому члену можно обратиться извне. В руководстве по стилю Godot приватные члены обозначаются начальным символом подчёркивания:
# bank_account.gd
class_name BankAccount
extends RefCounted
var owner_name: String
var _balance: int = 0
var _history: Array[String] = []
func _init(holder: String) -> void:
owner_name = holder
func deposit(amount: int) -> void:
_balance += amount
_record("deposit %d" % amount)
func get_balance() -> int:
return _balance
func _record(entry: String) -> void:
_history.append(entry)owner_name, deposit() и get_balance() являются общедоступными, поэтому они используются в main.gd. _balance, _history и _record() являются приватными: их использует только код внутри bank_account.gd.
# main.gd
var account := BankAccount.new("Ada")
account.deposit(50)
account.deposit(20)
print(account.owner_name) # Ada
print(account.get_balance()) # 70Подчёркивание — это соглашение, а не блокировка: account._balance = 1000000 в main.gd выполняется без ошибок. Всё равно придерживайся этого соглашения. Если только класс изменяет _balance, неправильный баланс может появиться только из-за метода в bank_account.gd, поэтому проверить нужно именно этот файл.
В GDScript тоже нет уровня protected. Подкласс наследует все члены, включая приватные, поэтому SavingsAccount, который extends BankAccount, может использовать _balance в своих методах.
Виртуальные методы Godot, такие как _init() и _ready(), тоже начинаются с символа подчёркивания. Godot вызывает их за вас, поэтому никогда не давайте своим приватным методам такие же имена.
Задание
ЛегкоЗаверши класс Hero в файле hero.gd. Его открытые члены — hero_name, gain_xp(), get_xp() и get_level(). Остальные — закрытые:
- Добавь закрытые переменные
_xp(начинается с0) и_level(начинается с1). - Добавь закрытый метод
_update_level(), который устанавливает значение_levelравным1 + _xp / 100(целочисленное деление). gain_xp(amount)добавляетamountк_xp, вызывает_update_level()и возвращаетtrue, если уровень повысился, иfalseв противном случае.get_xp()иget_level()возвращают закрытые значения.
Предоставленный код считывает имя героя, затем количество следующих значений XP, а затем по одному значению в каждой строке. После каждого значения он выводит строку Level up!, если gain_xp() возвращает true, а затем выводит состояние героя. Для Ada и значений 40, 70 и 250 он выводит:
Ada: 40 XP, level 1
Level up! Ada is now level 2
Ada: 110 XP, level 2
Level up! Ada is now level 4
Ada: 360 XP, level 4Твой код нужно поместить в hero.gd. В main.gd находится предоставленный код ввода/вывода, и его нельзя редактировать.
Попробуйте сами
extends Node
func _ready():
# Предоставленный код ввода/вывода: оставьте его без изменений
var hero := Hero.new(OS.read_string_from_stdin())
var count := int(OS.read_string_from_stdin())
for i in count:
var amount := int(OS.read_string_from_stdin())
if hero.gain_xp(amount):
print("Level up! %s is now level %d" % [hero.hero_name, hero.get_level()])
print("%s: %d XP, level %d" % [hero.hero_name, hero.get_xp(), hero.get_level()])
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово selfМетодыСвойстваКонструктор (_init)Повторение: простой калькулятор4Полиморфизм
Переопределение методов: повторениеУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовПовторение — калькулятор фигур7Сигналы
Что такое сигнал?Объявление и отправкаПодключение к сигналамСигналы с аргументамиПовторение — система здоровья10Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»2Свойства классов
Переменные экземпляра и классаСтатические функцииСеттеры свойствГеттеры свойствПриватность по соглашениюПовторение — менеджер банковского счёта5Инкапсуляция
Открытые и закрытые членыПроверка данных с помощью сеттеровСокрытие информацииСвойства только для чтенияПовторение — система учета студентов8Продвинутые концепции ООП
Композиция и наследованиеВнутренние классыУзлы как компонентыRefCounted и NodeПеречисления в классах11Проект: Управление библиотекой
Обзор проектаКлассы книг и пользователей3Наследование
Основы наследованияКлючевое слово superПереопределение методовЦепочки наследованияПроверка типов с помощью isПовторение — иерархия сотрудников6Специальные методы
Введение в виртуальные методыМетод _to_stringПользовательские итераторыПовторение: пользовательский список9Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн «Одиночка»Паттерн «Фабрика»Паттерн «Наблюдатель»Паттерн «Стратегия»Потренируйтесь самостоятельно: Онлайн-компилятор GDScript