Rückblick – Studierendendatensätze
Teil des Abschnitts Objektorientierte Programmierung der GO-Journey von Coddy. Lektion 51 von 107.
Aufgabe
EinfachErstellen wir ein Student-Records-System, das eine korrekte Kapselung demonstriert. Du erstellst eine Struktur zur Verwaltung von Studierenden, in der sensible akademische Daten geschützt werden und gleichzeitig über gut entworfene Methoden kontrollierter Zugriff möglich ist.
Du wirst deinen Code auf zwei Dateien aufteilen:
student.go: Erstelle eineStudent-Struktur, die sensible Informationen schützt und gleichzeitig sichere öffentliche Daten bereitstellt. DerNamedes Studierenden sollte exportiert (öffentlich zugänglich) sein, abergrade(float64) undstudentID(string) sollten nicht exportiert werden, um diese sensiblen Informationen zu schützen.Implementiere Folgendes:
- Einen Konstruktor
NewStudent(name, id string, initialGrade float64) *Student, der einen Studierenden erstellt. Die Anfangsnote sollte nur gesetzt werden, wenn sie zwischen 0 und 100 (einschließlich) liegt; andernfalls soll standardmäßig 0 verwendet werden. - Eine Getter-Methode
Grade() float64, die die aktuelle Note zurückgibt - Eine Getter-Methode
StudentID() string, die die Studierenden-ID zurückgibt - Eine Setter-Methode
SetGrade(newGrade float64) bool, die die Note nur aktualisiert, wenn der neue Wert zwischen 0 und 100 (einschließlich) liegt. Gibtruezurück, wenn die Note aktualisiert wurde, andernfallsfalse. - Eine Methode
Summary() string, die folgendes Format zurückgibt:[Name] (ID: [studentID]) - Grade: [grade]
- Einen Konstruktor
main.go: Lies die Informationen zum Studierenden aus der Eingabe ein, erstelle mithilfe des Konstruktors einen Studierenden und führe anschließend die Notenoperationen durch. Gib die Zusammenfassung des Studierenden nach der Erstellung und nach jedem Versuch einer Notenaktualisierung aus.
Die folgenden Eingaben werden bereitgestellt:
- Zeile 1: Name des Studierenden
- Zeile 2: Studierenden-ID
- Zeile 3: Anfangsnote
- Zeile 4: Erste neue zu setzende Note
- Zeile 5: Zweite neue zu setzende Note
Gib nach der Erstellung des Studierenden seine Zusammenfassung aus. Versuche anschließend, jede Notenaktualisierung durchzuführen. Wenn sie erfolgreich ist, gib die aktualisierte Zusammenfassung aus; wenn sie abgelehnt wird, gib Invalid grade rejected aus. Formatiere alle Notenwerte mit zwei Dezimalstellen.
Wenn beispielsweise Emma Wilson, STU001, 85.5, 92.0 und 150 gegeben sind, sollte deine Ausgabe folgendermaßen aussehen:
Emma Wilson (ID: STU001) - Grade: 85.50
Emma Wilson (ID: STU001) - Grade: 92.00
Invalid grade rejectedDie letzte Aktualisierung schlägt fehl, weil 150 außerhalb des gültigen Bereichs liegt. Deine Setter-Methode setzt diese Regel durch und hält die Daten des Studierenden gültig. Beachte, dass studentID und grade niemals direkt zugänglich sind: Externer Code muss deine Getter- und Setter-Methoden verwenden, um mit diesen geschützten Daten zu interagieren.
Probier es selbst
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Studentennamen lesen
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
// Studenten-ID lesen
id, _ := reader.ReadString('\n')
id = strings.TrimSpace(id)
// Anfangsnote lesen
initialGradeStr, _ := reader.ReadString('\n')
initialGrade, _ := strconv.ParseFloat(strings.TrimSpace(initialGradeStr), 64)
// Erste neue Note lesen
newGrade1Str, _ := reader.ReadString('\n')
newGrade1, _ := strconv.ParseFloat(strings.TrimSpace(newGrade1Str), 64)
// Zweite neue Note lesen
newGrade2Str, _ := reader.ReadString('\n')
newGrade2, _ := strconv.ParseFloat(strings.TrimSpace(newGrade2Str), 64)
// TODO: Erstelle einen neuen Studenten mit dem NewStudent-Konstruktor
// TODO: Gib die Zusammenfassung des Studenten nach der Erstellung aus
// TODO: Versuche die erste Notenaktualisierung
// Wenn erfolgreich, gib die aktualisierte Zusammenfassung aus
// If rejected, print "Invalid grade rejected"
// TODO: Versuche die zweite Notenaktualisierung
// Wenn erfolgreich, gib die aktualisierte Zusammenfassung aus
// If rejected, print "Invalid grade rejected"
// Hinweis: Verwende fmt.Sprintf mit %.2f zur Formatierung der Noten in Summary()
_ = newGrade1 // Entferne diese Zeile, wenn du die Variable verwendest
_ = newGrade2 // Entferne diese Zeile, wenn du die Variable verwendest
}
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP in Go
Externe DateienGo-Workspace & ModulePackages & ImportsExportierte vs. nicht exportierte NamenEinführung in OOP mit GoStructs als KlassenMethoden für Structs definierenPointer- vs. Value-ReceiverStruct-InitialisierungKonstruktorfunktionenRückblick – Einfacher Taschenrechner4Schnittstellen
Einführung in SchnittstellenImplizite ImplementierungSchnittstelle als VertragLeere Schnittstelle (any)TypzusicherungTypwechselZusammensetzung von SchnittstellenStringer- und Error-SchnittstellenRückblick – Formenrechner7Kapselung
Exportierte vs. nicht exportierte FelderKapselung auf PaketebeneGetter- und Setter-MethodenInformationsverbergung in GoRückblick – Studierendendatensätze10Generics (Go 1.18+)
Einführung in GenericsTypparameterTypbeschränkungenGenerische StrukturenWorkaround für generische MethodenZusammenfassung – Generische Sammlung2Typen & Structs im Detail
Grundlegende & zusammengesetzte TypenBenutzerdefinierte TypdefinitionenStruct-TagsAnonyme StructsVerschachtelte StructsNullwerte & StandardwerteRückblick – Kontaktbuch5Komposition statt Vererbung
Warum Go keine Vererbung hatGrundlagen der Struct-EinbettungMethoden-PromotionMehrere Structs einbettenEinbettung vs. AggregationVerbergen eingebetteter MethodenRückblick – Mitarbeiterhierarchie8Fehlerbehandlung & OOP
Das Error-InterfaceBenutzerdefinierte FehlertypenError-Wrapping (fmt.Errorf)Sentinel-Fehlererrors.Is() und errors.As()Panic, Defer und RecoverRückblick – Dateiparser3Zeiger & Speicher
Grundlagen von Zeigern in GoZeiger auf StructsÜbergabe per Wert vs. ReferenzDie Funktion new()Garbage Collection in GoRückblick – Verkettete Liste erstellen6Polymorphismus in Go
Polymorphismus über InterfacesDuck-Typing in GoRegeln zur Interface-ErfüllungPolymorphe SammlungenDependency InjectionZusammenfassung – Zahlungsprozessor9Konkurrenz & OOP
Grundlagen der GoroutinesChannels & KommunikationGepufferte vs. ungepufferte ChannelsSelect-Anweisungsync.Mutex & sync.RWMutexsync.WaitGroupThread-sicheres Struct-DesignRückblick – Worker PoolÜbe selbstständig: Online-Go-Compiler