Свойства только для чтения
Часть раздела Объектно-ориентированное программирование путешествия по GDScript на Coddy. Урок 29 из 65.
Некоторые значения должны быть доступны для чтения извне, но их нельзя присваивать: идентификатор, заданный один раз при создании объекта, или значение, вычисленное на основе других данных, например площадь или сумма. Для этого у свойства должен быть блок get без блока set:
# ticket.gd
class_name Ticket
extends RefCounted
var _number: int
var number: int:
get:
return _number
func _init(start_number: int) -> void:
_number = start_numberКонструктор сохраняет значение в закрытом _number, а открытый number только возвращает его. Присваивание значения number извне не является ошибкой, но ничего не меняет, потому что геттер продолжает возвращать _number:
var ticket := Ticket.new(42)
ticket.number = 7
print(ticket.number) # 42У вычисляемого свойства нет собственного значения: его геттер вычисляет значение каждый раз при чтении, поэтому оно всегда соответствует данным, из которых получено:
# room.gd
class_name Room
extends RefCounted
var width: int = 4
var length: int = 5
var area: int:
get:
return width * lengthvar room := Room.new()
print(room.area) # 20
room.width = 6
print(room.area) # 30Обычную переменную var area пришлось бы обновлять вручную каждый раз, когда меняется width или length, а одно забытое обновление приведёт к неверному значению. Вычисляемая area не может устареть, и никто не сможет присвоить ей неверное значение.
Для значения, которое одинаково для каждого объекта и никогда не меняется, используй константу в классе: const MAX_GUESTS = 4. О присваивании константе сообщается до запуска программы.
Задание
ЛегкоКласс Order в файле order.gd хранит свой идентификатор в _id, а сумму для каждой позиции — в _line_totals (цена умножить на количество). Сделай четыре общедоступных свойства доступными только для чтения с помощью блоков get:
order_idвозвращает_id.subtotalвозвращает сумму значений_line_totals.shippingвозвращает0, если промежуточная сумма составляет50или больше, в противном случае —5.totalвозвращает промежуточную сумму плюс стоимость доставки.
Предоставленный код считывает идентификатор заказа, количество товаров, а затем по одной строке price quantity для каждого товара. После каждого товара он выводит промежуточную сумму, стоимость доставки и итоговую сумму. В конце он пытается присвоить всем четырём свойствам значение 0, а затем выводит идентификатор и итоговую сумму, которые должны остаться неизменными. Для идентификатора 7 и товаров 12 2 и 30 1 он выводит:
Subtotal 24, shipping 5, total 29
Subtotal 54, shipping 0, total 54
Order #7: 54Твой код должен быть в файле order.gd. В main.gd находится предоставленный код ввода/вывода, и его нельзя редактировать.
Попробуйте сами
extends Node
func _ready():
# Предоставленный код ввода-вывода: оставьте его без изменений
var order := Order.new(int(OS.read_string_from_stdin()))
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
order.add_item(int(parts[0]), int(parts[1]))
print("Subtotal %d, shipping %d, total %d" % [order.subtotal, order.shipping, order.total])
# Код, который пытается перезаписать свойства, доступные только для чтения
order.order_id = 0
order.subtotal = 0
order.shipping = 0
order.total = 0
print("Order #%d: %d" % [order.order_id, order.total])
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово selfМетодыСвойстваКонструктор (_init)Повторение: простой калькулятор4Полиморфизм
Переопределение методов: повторениеУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовПовторение — калькулятор фигур7Сигналы
Что такое сигнал?Объявление и отправкаПодключение к сигналамСигналы с аргументамиПовторение — система здоровья10Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»2Свойства классов
Переменные экземпляра и классаСтатические функцииСеттеры свойствГеттеры свойствПриватность по соглашениюПовторение — менеджер банковского счёта5Инкапсуляция
Открытые и закрытые членыПроверка данных с помощью сеттеровСокрытие информацииСвойства только для чтенияПовторение — система учета студентов8Продвинутые концепции ООП
Композиция и наследованиеВнутренние классыУзлы как компонентыRefCounted и NodeПеречисления в классах11Проект: Управление библиотекой
Обзор проектаКлассы книг и пользователей3Наследование
Основы наследованияКлючевое слово superПереопределение методовЦепочки наследованияПроверка типов с помощью isПовторение — иерархия сотрудников6Специальные методы
Введение в виртуальные методыМетод _to_stringПользовательские итераторыПовторение: пользовательский список9Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн «Одиночка»Паттерн «Фабрика»Паттерн «Наблюдатель»Паттерн «Стратегия»Потренируйтесь самостоятельно: Онлайн-компилятор GDScript