Menu
CoddyTech

Свойства только для чтения

Часть раздела Объектно-ориентированное программирование путешествия по 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 * length
var room := Room.new()
print(room.area) # 20
room.width = 6
print(room.area) # 30

Обычную переменную var area пришлось бы обновлять вручную каждый раз, когда меняется width или length, а одно забытое обновление приведёт к неверному значению. Вычисляемая area не может устареть, и никто не сможет присвоить ей неверное значение.

Для значения, которое одинаково для каждого объекта и никогда не меняется, используй константу в классе: const MAX_GUESTS = 4. О присваивании константе сообщается до запуска программы.

challenge icon

Задание

Легко

Класс 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])
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор GDScript