Powtórka – dane studentów
Część sekcji Programowanie obiektowe ścieżki GO w Coddy. Lekcja 51 z 107.
Wyzwanie
ŁatwyStwórzmy system ewidencji studentów, który pokazuje prawidłową enkapsulację. Utworzysz strukturę do zarządzania studentami, w której wrażliwe dane akademickie będą chronione, a jednocześnie dostęp do nich będzie kontrolowany za pomocą dobrze zaprojektowanych metod.
Podzielisz kod na dwa pliki:
student.go: Utwórz strukturęStudent, która chroni wrażliwe informacje, udostępniając jednocześnie bezpieczne dane publiczne. PoleNamestudenta powinno być eksportowane (publicznie dostępne), natomiast polagrade(float64) istudentID(string) powinny być nieeksportowane, aby chronić te wrażliwe informacje.Zaimplementuj następujące elementy:
- Konstruktor
NewStudent(name, id string, initialGrade float64) *Student, który tworzy studenta. Początkowa ocena powinna być ustawiona tylko wtedy, gdy mieści się w zakresie od 0 do 100 (włącznie); w przeciwnym razie ustaw wartość domyślną 0. - Getter
Grade() float64, który zwraca bieżącą ocenę - Getter
StudentID() string, który zwraca identyfikator studenta - Setter
SetGrade(newGrade float64) bool, który aktualizuje ocenę tylko wtedy, gdy nowa wartość mieści się w zakresie od 0 do 100 (włącznie). Zwróćtrue, jeśli ocena została zaktualizowana, a w przeciwnym raziefalse. - Metodę
Summary() string, która zwraca tekst w formacie:[Name] (ID: [studentID]) - Grade: [grade]
- Konstruktor
main.go: Odczytaj informacje o studencie z wejścia, utwórz studenta za pomocą konstruktora, a następnie wykonaj operacje na ocenach. Wyświetl podsumowanie studenta po utworzeniu oraz po każdej próbie aktualizacji oceny.
Podane zostaną następujące dane wejściowe:
- Wiersz 1: Imię i nazwisko studenta
- Wiersz 2: Identyfikator studenta
- Wiersz 3: Początkowa ocena
- Wiersz 4: Pierwsza nowa ocena do ustawienia
- Wiersz 5: Druga nowa ocena do ustawienia
Po utworzeniu studenta wyświetl jego podsumowanie. Następnie spróbuj zaktualizować każdą ocenę; jeśli aktualizacja się powiedzie, wyświetl zaktualizowane podsumowanie, a jeśli zostanie odrzucona, wyświetl Invalid grade rejected. Formatuj wszystkie oceny z dokładnością do dwóch miejsc po przecinku.
Na przykład dla danych Emma Wilson, STU001, 85.5, 92.0 i 150 wynik powinien wyglądać następująco:
Emma Wilson (ID: STU001) - Grade: 85.50
Emma Wilson (ID: STU001) - Grade: 92.00
Invalid grade rejectedOstatnia aktualizacja nie powiedzie się, ponieważ 150 wykracza poza dozwolony zakres. Metoda setter egzekwuje tę zasadę, dzięki czemu dane studenta pozostają prawidłowe. Zwróć uwagę, że pola studentID i grade nigdy nie są bezpośrednio dostępne: kod zewnętrzny musi używać metod getter i setter, aby korzystać z tych chronionych danych.
Spróbuj swoich sił
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Odczytaj imię i nazwisko studenta
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
// Odczytaj identyfikator studenta
id, _ := reader.ReadString('\n')
id = strings.TrimSpace(id)
// Odczytaj ocenę początkową
initialGradeStr, _ := reader.ReadString('\n')
initialGrade, _ := strconv.ParseFloat(strings.TrimSpace(initialGradeStr), 64)
// Odczytaj pierwszą nową ocenę
newGrade1Str, _ := reader.ReadString('\n')
newGrade1, _ := strconv.ParseFloat(strings.TrimSpace(newGrade1Str), 64)
// Odczytaj drugą nową ocenę
newGrade2Str, _ := reader.ReadString('\n')
newGrade2, _ := strconv.ParseFloat(strings.TrimSpace(newGrade2Str), 64)
// TODO: Utwórz nowego studenta za pomocą konstruktora NewStudent
// TODO: Wypisz podsumowanie studenta po jego utworzeniu
// TODO: Spróbuj po raz pierwszy zaktualizować ocenę
// Jeśli się powiedzie, wypisz zaktualizowane podsumowanie
// Jeśli aktualizacja zostanie odrzucona, wypisz "Invalid grade rejected"
// TODO: Spróbuj po raz drugi zaktualizować ocenę
// Jeśli się powiedzie, wypisz zaktualizowane podsumowanie
// Jeśli aktualizacja zostanie odrzucona, wypisz "Invalid grade rejected"
// Wskazówka: Użyj fmt.Sprintf z %.2f do formatowania ocen w Summary()
_ = newGrade1 // Usuń tę linię, gdy zaczniesz używać zmiennej
_ = newGrade2 // Usuń tę linię, gdy zaczniesz używać zmiennej
}
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy OOP w Go
Pliki zewnętrzneObszar roboczy i moduły GoPakiety i importyNazwy eksportowane i nieeksportowaneWprowadzenie do OOP w GoStruktury jako klasyDefiniowanie metod dla strukturOdbiorniki wskaźnikowe i wartościoweInicjalizacja strukturFunkcje konstruktoraPodsumowanie – prosty kalkulator4Interfejsy
Wprowadzenie do interfejsówImplementacja niejawnaInterfejs jako kontraktPusty interfejs (any)Asercja typuPrzełącznik typówKompozycja interfejsówInterfejsy Stringer i ErrorPowtórka — kalkulator figur7Hermetyzacja
Pola eksportowane i nieeksportowaneHermetyzacja na poziomie pakietuMetody pobierające i ustawiająceUkrywanie informacji w GoPowtórka – dane studentów10Typy generyczne (Go 1.18+)
Wprowadzenie do typów generycznychParametry typówOgraniczenia typówStruktury generyczneObejście ograniczeń metod generycznychPodsumowanie — generyczna kolekcja2Typy i struktury w praktyce
Typy proste i złożoneDefiniowanie własnych typówTagi pól strukturStruktury anonimoweStruktury zagnieżdżoneWartości zerowe i domyślnePodsumowanie – książka kontaktów5Kompozycja zamiast dziedziczenia
Dlaczego Go nie ma dziedziczeniaPodstawy osadzania strukturPromowanie metodOsadzanie wielu strukturOsadzanie a agregacjaPrzesłanianie osadzonych metodPodsumowanie — hierarchia pracowników8Obsługa błędów i programowanie obiektowe
Interfejs błęduWłasne typy błędówOpakowywanie błędów (fmt.Errorf)Błędy wartowniczeerrors.Is() i errors.As()Panic, Defer i RecoverPodsumowanie — parser plików3Wskaźniki i pamięć
Podstawy wskaźników w GoWskaźniki do strukturPrzekazywanie przez wartość a przez referencjęFunkcja new()Odśmiecanie pamięci w GoPowtórka — kreator listy wiązanej6Polimorfizm w Go
Polimorfizm za pomocą interfejsówDuck typing w GoZasady spełniania interfejsówKolekcje polimorficzneWstrzykiwanie zależnościPowtórka — procesor płatności9Współbieżność i OOP
Podstawy goroutinesKanały i komunikacjaKanały buforowane i niebuforowaneInstrukcja selectsync.Mutex i sync.RWMutexsync.WaitGroupProjektowanie struktur bezpiecznych wątkowoPowtórka – pula workerów12Zaawansowane zagadnienia programowania obiektowego
Wzorzec opcji funkcyjnychWzorzec Builder w GoŁańcuchowe wywoływanie metodAliasy typów a definicje typówPodstawy refleksjiPrzegląd generowania koduPoćwicz samodzielnie: Kompilator Go online