Validierung mit Settern
Teil des Abschnitts Objektorientierte Programmierung der GDScript-Journey von Coddy. Lektion 27 von 65.
Ein Setter wird jedes Mal ausgeführt, wenn seiner Eigenschaft ein Wert zugewiesen wird. Daher ist er der richtige Ort, um den neuen Wert zu prüfen. Python löst bei einem ungültigen Wert einen Fehler aus. GDScript kennt keine Ausnahmen, daher macht ein Setter stattdessen eines von zwei Dingen: Er begrenzt den Wert auf den zulässigen Bereich oder behält den alten Wert bei und hält fest, was schiefgelaufen ist.
# character.gd
class_name Character
extends RefCounted
var last_error: String = ""
var hp: int = 100:
set(value):
hp = clampi(value, 0, 100)
var nickname: String = "Player":
set(value):
if value.length() < 3:
last_error = "Name too short"
return
last_error = ""
nickname = valueclampi(value, 0, 100) verschiebt value in den Bereich von 0 bis 100. Im Setter von nickname wird vor der Zuweisung mit return abgebrochen, sodass der alte Name erhalten bleibt und last_error den Grund angibt:
# main.gd
var hero := Character.new()
hero.hp = 250
print(hero.hp) # 100
hero.nickname = "Al"
print(hero.nickname) # Spieler
print(hero.last_error) # Name zu kurz
hero.nickname = "Alice"
print(hero.nickname) # AliceDer Setter wird auch bei Zuweisungen innerhalb der Klasse ausgeführt, in _init() und in jeder Methode. Weise die Argumente des Konstruktors über die Eigenschaft zu, dann werden sie ebenfalls überprüft:
func _init(start_hp: int) -> void:
hp = start_hp # ruft den Setter auf: Character.new(500) startet mit 100Im Setter selbst speichert die Zuweisung von hp den Wert, ohne den Setter erneut aufzurufen. Die einzige Zuweisung, die den Setter überspringt, ist der Anfangswert in der Deklaration (= 100), daher muss dieser Wert für sich genommen gültig sein.
Aufgabe
EinfachFüge der Klasse Thermostat in thermostat.gd mit Settern eine Validierung hinzu:
target(startet bei20) akzeptiert nur Werte von10bis30. Bei jedem anderen Wert behält es den alten Zielwert bei und setztlast_erroraufTarget must be between 10 and 30.mode(startet beioff) akzeptiert nurheat,coolundoff. Bei jedem anderen Text behält es den alten Modus bei und setztlast_erroraufUnknown mode:, gefolgt vom Text.- Bei einer gültigen Zuweisung wird
last_errorwieder auf eine leere Zeichenfolge gesetzt. _init(start_target)weiststart_targetdem Werttargetzu, sodass der Setter ihn überprüft.
Der bereitgestellte Code liest den Startwert, dann die Anzahl der Befehle und anschließend einen Befehl pro Zeile (target 25 oder mode cool). Nach dem Erstellen des Thermostats und nach jedem Befehl gibt er Rejected: und den Fehler aus, wenn last_error nicht leer ist, und anschließend den Zustand. Für den Startwert 22 und die Befehle target 35 und mode cool gibt er Folgendes aus:
Target 22, mode off
Rejected: Target must be between 10 and 30
Target 22, mode off
Target 22, mode coolDein Code gehört in thermostat.gd. main.gd enthält den bereitgestellten Ein-/Ausgabecode und kann nicht bearbeitet werden.
Probier es selbst
extends Node
func _ready():
# Vorgegebener Eingabe-/Ausgabecode: unverändert lassen
var thermostat := Thermostat.new(int(OS.read_string_from_stdin()))
report(thermostat)
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
if parts[0] == "target":
thermostat.target = int(parts[1])
else:
thermostat.mode = parts[1]
report(thermostat)
func report(thermostat: Thermostat) -> void:
if thermostat.last_error != "":
print("Rejected: " + thermostat.last_error)
print("Target %d, mode %s" % [thermostat.target, thermostat.mode])
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