Menu
CoddyTech

Design de Interfaces

Parte da seção Programação orientada a objetos do Journey de GDScript da Coddy. Lição 24 de 65.

Uma interface é uma lista de métodos que uma classe promete ter, sem código por trás deles. Java e C# têm uma palavra-chave interface; GDScript não. Você cria a mesma coisa a partir de uma classe abstrata cujos métodos são todos abstratos:

# drawable.gd
@abstract
class_name Drawable
extends RefCounted

@abstract func draw() -> String
@abstract func resize(factor: int) -> void

Ela não tem variáveis nem corpos de métodos. Ela descreve o que algo desenhável pode fazer, e cada classe decide como:

# 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 *= factor

Um Circle também pode estender Drawable, com um radius e seus próprios draw() e resize(). O código que usa a interface depende apenas dela, então funciona com todas as classes que estendem Drawable, incluindo as que forem escritas posteriormente:

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

Uma classe tem um pai, então só pode estender uma interface. Quando uma classe desempenha uma segunda função, como ser salva em um arquivo, estenda a interface principal e verifique a segunda função com has_method():

if item.has_method("save"):
	item.save()

Mantenha cada interface pequena: alguns métodos que pertencem a uma função. Assim, uma classe que a estende escreve apenas os métodos de que precisa.

challenge icon

Desafio

Fácil

Crie um reprodutor de mídia baseado em uma interface.

  • Em playable.gd, transforme Playable em uma interface: uma classe abstrata com os métodos abstratos play() -> String e duration() -> int (em segundos).
  • Song estende Playable. play() retorna Playing song: TITLE by ARTIST, e duration() retorna sua duração em segundos.
  • Video estende Playable. play() retorna Playing video: TITLE in RESOLUTIONp (por exemplo, in 1080p), e duration() retorna sua duração em segundos.
  • Playlist conhece apenas Playable. play_all() exibe o resultado de play() de cada item, e total_time() retorna a duração total no formato M:SS (segundos com dois dígitos, por exemplo, 4:05).

Os construtores de Song e Video já estão escritos. O código fornecido lê quantos itens vêm a seguir e, depois, uma linha por item: song TITLE ARTIST SECONDS ou video TITLE RESOLUTION SECONDS. Ele chama play_all() e exibe o tempo total. Para song Imagine Lennon 183 e video Trailer 1080 95, ele exibe:

Playing song: Imagine by Lennon
Playing video: Trailer in 1080p
Total time: 4:38

Seu código deve ficar em playable.gd, song.gd, video.gd e playlist.gd. main.gd contém o código de entrada/saída fornecido e não pode ser editado.

Experimente você mesmo

extends Node

func _ready():
	# Código de entrada/saída fornecido: mantenha-o como está
	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())
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação orientada a objetos

Pratique por conta própria: Compilador de GDScript online