Menu
CoddyTech

Внутренние классы

Часть раздела Объектно-ориентированное программирование путешествия по GDScript на Coddy. Урок 41 из 65.

Класс может объявить внутри себя другой класс с помощью ключевого слова class, указания имени и тела с отступом. Этот вложенный класс — вспомогательный тип, принадлежащий внешнему классу:

# inventory.gd
class_name Inventory
extends RefCounted

const MAX_STACK := 5

class Slot:
	var item_name: String
	var count: int

	func _init(new_name: String, new_count: int) -> void:
		item_name = new_name
		count = mini(new_count, MAX_STACK)

	func _to_string() -> String:
		return "%s x%d" % [item_name, count]

var slots: Array[Slot] = []

func add(item_name: String, count: int) -> Slot:
	var slot := Slot.new(item_name, count)
	slots.append(slot)
	return slot

Внутри inventory.gd находится внутренний класс Slot. Все остальные файлы обращаются к нему через внешний класс: Inventory.Slot.

# main.gd
var bag := Inventory.new()
bag.add("Potion", 9)
var arrows: Inventory.Slot = bag.add("Arrow", 3)
print(bag.slots)    # [Potion x5, Arrow x3]
var gem := Inventory.Slot.new("Gem", 1)

Внутренний класс без extends наследуется от RefCounted и, как и любой класс, может иметь переменные, конструктор и методы. Он может использовать константы и перечисления внешнего класса (например, MAX_STACK выше), но не его переменные-члены: у Slot нет доступа к slots, потому что слот — это отдельный объект. Передавай ему в конструктор все необходимые значения.

Используй вложенный класс для небольшого типа, который имеет смысл только вместе с внешним классом, например для ячейки инвентаря или записи в таблице результатов. Тип, который другие части игры используют самостоятельно, заслуживает собственного файла и class_name.

challenge icon

Задание

Легко

Создай Leaderboard, записи которого являются внутренним классом.

  • Объяви внутренний класс Entry внутри Leaderboard, задав player_name и score в его конструкторе, а также сделав так, чтобы _to_string() возвращал Ada: 120.
  • entries — типизированный массив Entry, упорядоченный по первому появлению игроков.
  • submit(player, score) добавляет новую запись для нового игрока. Если запись для игрока уже есть, сохраняется большее из двух значений.
  • best() возвращает запись с наибольшим значением. При равенстве побеждает запись, которая появляется первой.

Предоставленный код считывает, сколько значений следует далее (Ada 120), добавляет их, затем выводит каждую запись и лучшую (всегда передаётся как минимум одно значение). Для Ada 120, Bo 90, Ada 80, Bo 150, Cy 150 он выводит:

Ada: 120
Bo: 150
Cy: 150
Best: Bo: 150

Твой код нужно поместить в leaderboard.gd. В main.gd находится предоставленный код ввода/вывода, его нельзя редактировать.

Попробуйте сами

extends Node

func _ready():
	# Предоставленный код ввода/вывода: оставьте его без изменений
	var board := Leaderboard.new()
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		board.submit(parts[0], int(parts[1]))
	for entry in board.entries:
		print(entry)
	print("Best: ", board.best())
quiz iconПроверьте себя

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

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

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