Informationsverbergen
Teil des Abschnitts Objektorientierte Programmierung der GDScript-Journey von Coddy. Lektion 28 von 65.
Informationsverbergung geht einen Schritt weiter als private Variablen: Code, der eine Klasse verwendet, hängt nur davon ab, was ihre öffentlichen Methoden tun, niemals davon, wie die Klasse ihre Daten speichert. Dann kannst du die Speicherung ändern, ohne diesen Code anzufassen.
# inventory.gd
class_name Inventory
extends RefCounted
var _counts: Dictionary = {}
func add(item: String, amount: int) -> void:
_counts[item] = _counts.get(item, 0) + amount
func count(item: String) -> int:
return _counts.get(item, 0)
func remove(item: String, amount: int) -> bool:
if count(item) < amount:
return false
_counts[item] -= amount
return truemain.gd ruft add(), count() und remove() auf und bekommt das Dictionary nie zu Gesicht. Wenn Inventory später stattdessen ein Array von Slots enthält, ändert sich nur inventory.gd.
Sei vorsichtig mit Gettern, die ein Array oder ein Dictionary zurückgeben. GDScript gibt diese Werte als Referenz weiter: Der Aufrufer erhält das eigene Array des Objekts, keine Kopie, und kann es ändern, ohne die Methoden der Klasse aufzurufen:
# quest_log.gd
var _quests: Array[String] = ["Find the key"]
func get_quests() -> Array[String]:
return _quests# main.gd
var journal := QuestLog.new()
var quests := journal.get_quests()
quests.append("Skip the boss")
print(journal.get_quests()) # ["Find the key", "Skip the boss"]Gib stattdessen eine Kopie zurück. duplicate() erstellt ein neues Array mit denselben Elementen, sodass Änderungen daran außerhalb des Objekts bleiben:
func get_quests() -> Array[String]:
return _quests.duplicate()Für ein Dictionary oder ein Array, das andere Arrays enthält, verwende duplicate(true): Dadurch werden auch die inneren Arrays und Dictionaries kopiert.
Aufgabe
EinfachSchreibe die Klasse Playlist in playlist.gd. Sie speichert die Songtitel im privaten Array _songs, und anderer Code verwendet nur diese Methoden:
add(title)fügt den Titel hinzu und gibttruezurück. Wenn der Titel bereits in der Playlist enthalten ist, ändert die Methode nichts und gibtfalsezurück.remove(title)entfernt den Titel und gibttruezurück oder gibtfalsezurück, wenn der Titel nicht enthalten ist.count()gibt die Anzahl der Songs zurück.get_titles()gibt eine Kopie der Titel in der Reihenfolge zurück, in der sie hinzugefügt wurden.
Der bereitgestellte Code liest die Anzahl der Befehle und dann einen Befehl pro Zeile (add Blue Sky oder remove Blue Sky) und gibt das Ergebnis aus. Am Ende nimmt er das Array von get_titles(), fügt Intruder hinzu und kehrt die Reihenfolge um. Anschließend gibt er die Anzahl der Songs und die Titel aus. Deine Playlist darf von diesen Änderungen nicht beeinflusst werden. Für die Befehle add Blue Sky, add Rain und add Blue Sky gibt der Code Folgendes aus:
Added: Blue Sky
Added: Rain
Already in the playlist: Blue Sky
Songs: 2
Blue Sky, RainDein Code gehört in playlist.gd. main.gd enthält den bereitgestellten Ein-/Ausgabecode und darf nicht bearbeitet werden.
Probier es selbst
extends Node
func _ready():
# Vorgegebener Ein-/Ausgabecode: unverändert lassen
var playlist := Playlist.new()
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ", true, 1)
var title := parts[1]
if parts[0] == "add":
if playlist.add(title):
print("Added: " + title)
else:
print("Already in the playlist: " + title)
elif playlist.remove(title):
print("Removed: " + title)
else:
print("Not found: " + title)
# Code, der versucht, die zurückgegebene Liste zu verändern
var titles := playlist.get_titles()
titles.append("Intruder")
titles.reverse()
print("Songs: %d" % playlist.count())
print(", ".join(playlist.get_titles()))
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