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) -> voidEs 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 *= factorEin 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 6Eine 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.
Aufgabe
EinfachErstelle einen Mediaplayer rund um eine Schnittstelle.
- Mach
Playableinplayable.gdzu einer Schnittstelle: einer abstrakten Klasse mit den abstrakten Methodenplay() -> Stringundduration() -> int(in Sekunden). SongerweitertPlayable.play()gibtPlaying song: TITLE by ARTISTzurück, undduration()gibt die Sekunden zurück.VideoerweitertPlayable.play()gibtPlaying video: TITLE in RESOLUTIONpzurück (zum Beispielin 1080p), undduration()gibt die Sekunden zurück.Playlistkennt nurPlayable.play_all()gibtplay()für jedes Element aus, undtotal_time()gibt die aufsummierte Dauer im FormatM:SSzurück (Sekunden mit zwei Ziffern, zum Beispiel4: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:38Dein 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())
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas Schlüsselwort selfMethodenEigenschaftenKonstruktor (_init)Wiederholung – Einfacher Taschenrechner4Polymorphie
Methodenüberschreibung erneut betrachtetDuck-TypisierungAbstrakte Klassen und MethodenSchnittstellendesignRückblick – Formrechner2Klassenattribute
Instanz- vs. statische VariablenStatische FunktionenProperty-SetterProperty-GetterPrivat nach KonventionWiederholung – Bankkontenverwaltung5Kapselung
Öffentliche und private MemberValidierung mit SetternInformationsverbergenSchreibgeschützte EigenschaftenRückblick – System zur Schülerverwaltung8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungInnere KlassenNodes als KomponentenRefCounted vs. NodeEnums in Klassen11Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Vererbung
Grundlegende VererbungDas Schlüsselwort superMethodenüberschreibungVererbungskettenTypprüfungen mit isWiederholung – Mitarbeiterhierarchie6Spezielle Methoden
Einführung in virtuelle MethodenDie _to_string-MethodeBenutzerdefinierte IteratorenRückblick – Benutzerdefinierte Liste9Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterBeobachter-MusterStrategie-Muster12Abschließende Herausforderungen
E-Learning-PlattformBankensystemEntwicklung von SpielfigurenFahrzeugvermietungÜbe selbstständig: Online-GDScript-Compiler