Проектирование интерфейсов
Часть раздела Объектно-ориентированное программирование путешествия по GDScript на Coddy. Урок 24 из 65.
Интерфейс — это список методов, которые класс обещает иметь, но без реализации. В Java и C# есть ключевое слово interface; в GDScript его нет. То же самое можно создать с помощью абстрактного класса, все методы которого являются абстрактными:
# drawable.gd
@abstract
class_name Drawable
extends RefCounted
@abstract func draw() -> String
@abstract func resize(factor: int) -> voidВ нём нет переменных и тел методов. Он описывает, что может делать рисуемый объект, а каждый класс сам решает, как именно:
# banner.gd
class_name Banner
extends Drawable
var text: String
var size := 1
func _init(t: String) -> void:
text = t
func draw() -> String:
return "Banner '%s' at size %d" % [text, size]
func resize(factor: int) -> void:
size *= factorCircle тоже может расширять Drawable, иметь radius и собственные методы draw() и resize(). Код, использующий интерфейс, зависит только от него, поэтому он работает с каждым классом, который расширяет Drawable, включая классы, написанные позднее:
func render_all(items: Array[Drawable]) -> void:
for item in items:
item.resize(2)
print(item.draw())var items: Array[Drawable] = [Banner.new("Sale"), Circle.new(3)]
render_all(items)Banner 'Sale' at size 2
Circle with radius 6У класса есть один родитель, поэтому он может расширять только один интерфейс. Когда класс выполняет вторую роль, например сохраняется в файл, расширь основной интерфейс и проверь вторую роль с помощью has_method():
if item.has_method("save"):
item.save()Делайте каждый интерфейс небольшим: несколько методов, относящихся к одной роли. Класс, который его расширяет, затем реализует только необходимые ему методы.
Задание
ЛегкоСоздай медиаплеер на основе интерфейса.
- В
playable.gdсделайPlayableинтерфейсом: абстрактным классом с абстрактными методамиplay() -> Stringиduration() -> int(в секундах). Songнаследуется отPlayable. Методplay()возвращаетPlaying song: TITLE by ARTIST, аduration()возвращает длительность в секундах.Videoнаследуется отPlayable. Методplay()возвращаетPlaying video: TITLE in RESOLUTIONp(например,in 1080p), аduration()возвращает длительность в секундах.Playlistзнает только оPlayable. Методplay_all()выводит результатplay()каждого элемента, аtotal_time()возвращает суммарную длительность в форматеM:SS(секунды записываются двумя цифрами, например,4:05).
Конструкторы Song и Video уже написаны. Предоставленный код считывает количество следующих элементов, а затем по одной строке на каждый элемент: song TITLE ARTIST SECONDS или video TITLE RESOLUTION SECONDS. Он вызывает play_all() и выводит общее время. Для song Imagine Lennon 183 и video Trailer 1080 95 он выводит:
Playing song: Imagine by Lennon
Playing video: Trailer in 1080p
Total time: 4:38Твой код нужно написать в playable.gd, song.gd, video.gd и playlist.gd. В main.gd находится предоставленный код ввода и вывода, его нельзя редактировать.
Попробуйте сами
extends Node
func _ready():
# Предоставленный код ввода-вывода: оставьте его без изменений
var count := int(OS.read_string_from_stdin())
var playlist := Playlist.new()
for i in count:
var p := OS.read_string_from_stdin().split(" ")
if p[0] == "song":
playlist.add(Song.new(p[1], p[2], int(p[3])))
else:
playlist.add(Video.new(p[1], int(p[2]), int(p[3])))
playlist.play_all()
print("Total time: " + playlist.total_time())
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово selfМетодыСвойстваКонструктор (_init)Повторение: простой калькулятор4Полиморфизм
Переопределение методов: повторениеУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовПовторение — калькулятор фигур7Сигналы
Что такое сигнал?Объявление и отправкаПодключение к сигналамСигналы с аргументамиПовторение — система здоровья10Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»2Свойства классов
Переменные экземпляра и классаСтатические функцииСеттеры свойствГеттеры свойствПриватность по соглашениюПовторение — менеджер банковского счёта5Инкапсуляция
Открытые и закрытые членыПроверка данных с помощью сеттеровСокрытие информацииСвойства только для чтенияПовторение — система учета студентов8Продвинутые концепции ООП
Композиция и наследованиеВнутренние классыУзлы как компонентыRefCounted и NodeПеречисления в классах11Проект: Управление библиотекой
Обзор проектаКлассы книг и пользователей3Наследование
Основы наследованияКлючевое слово superПереопределение методовЦепочки наследованияПроверка типов с помощью isПовторение — иерархия сотрудников6Специальные методы
Введение в виртуальные методыМетод _to_stringПользовательские итераторыПовторение: пользовательский список9Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн «Одиночка»Паттерн «Фабрика»Паттерн «Наблюдатель»Паттерн «Стратегия»Потренируйтесь самостоятельно: Онлайн-компилятор GDScript