Menu
CoddyTech

Schnittstellendesign

Teil des Abschnitts Objektorientierte Programmierung der GDScript-Journey von Coddy. Lektion 24 von 65.

Ein Interface ist eine Liste von Methoden, die eine Klasse bereitzustellen verspricht, ohne dass dahinter Code steht. Java und C# haben ein interface-Schlüsselwort; GDScript nicht. Du erstellst dasselbe mithilfe einer abstrakten Klasse, deren Methoden alle abstrakt sind:

# drawable.gd
@abstract
class_name Drawable
extends RefCounted

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

Es enthält keine Variablen und keine Methodenrümpfe. Es beschreibt, was ein zeichnbares Objekt tun kann, und jede Klasse entscheidet, wie:

# 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

Ein Circle kann ebenfalls Drawable erweitern, mit einem radius und eigenen Methoden draw() und resize(). Code, der die Schnittstelle verwendet, hängt nur von ihr ab, sodass er mit jeder Klasse funktioniert, die Drawable erweitert, auch mit später geschriebenen:

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

Eine Klasse hat ein Elternteil und kann daher nur eine Schnittstelle erweitern. Wenn eine Klasse eine zweite Rolle übernimmt, zum Beispiel indem sie in einer Datei gespeichert wird, erweitere die Hauptschnittstelle und prüfe die zweite Rolle mit has_method():

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

Halte jede Schnittstelle klein: einige wenige Methoden, die zu einer Aufgabe gehören. Eine Klasse, die sie erweitert, schreibt dann nur die Methoden, die sie benötigt.

challenge icon

Aufgabe

Einfach

Erstelle einen Mediaplayer rund um eine Schnittstelle.

  • Mach Playable in playable.gd zu einer Schnittstelle: einer abstrakten Klasse mit den abstrakten Methoden play() -> String und duration() -> int (in Sekunden).
  • Song erweitert Playable. play() gibt Playing song: TITLE by ARTIST zurück, und duration() gibt die Sekunden zurück.
  • Video erweitert Playable. play() gibt Playing video: TITLE in RESOLUTIONp zurück (zum Beispiel in 1080p), und duration() gibt die Sekunden zurück.
  • Playlist kennt nur Playable. play_all() gibt play() für jedes Element aus, und total_time() gibt die aufsummierte Dauer im Format M:SS zurück (Sekunden mit zwei Ziffern, zum Beispiel 4:05).

Die Konstruktoren von Song und Video sind bereits geschrieben. Der bereitgestellte Code liest ein, wie viele Elemente folgen, und danach eine Zeile pro Element: song TITLE ARTIST SECONDS oder video TITLE RESOLUTION SECONDS. Er ruft play_all() auf und gibt die Gesamtzeit aus. Für song Imagine Lennon 183 und video Trailer 1080 95 gibt er Folgendes aus:

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

Dein Code gehört in playable.gd, song.gd, video.gd und playlist.gd. main.gd enthält den bereitgestellten Ein-/Ausgabecode und kann nicht bearbeitet werden.

Probier es selbst

extends Node

func _ready():
	# Vorgegebener Ein-/Ausgabecode: unverändert lassen
	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 dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-GDScript-Compiler