Menu
Coddy logo textTech

Metody pobierające i ustawiające

Część sekcji Programowanie obiektowe ścieżki GO w Coddy. Lekcja 49 z 107.

Ponieważ pola nieeksportowane nie mogą być bezpośrednio używane spoza pakietu, musisz udostępnić metody umożliwiające kontrolowany dostęp. Są one powszechnie nazywane metodami pobierającymi i metodami ustawiającymi.

W Go konwencja dotycząca getterów jest prosta: używaj nazwy pola z wielką pierwszą literą. Nie dodawaj prefiksu „Get”, po prostu użyj Balance(), a nie GetBalance():

type BankAccount struct {
    balance int  // nieeksportowane
}

// Getter - zwraca wartość
func (b *BankAccount) Balance() int {
    return b.balance
}

// Setter - modyfikuje wartość po sprawdzeniu jej poprawności
func (b *BankAccount) SetBalance(amount int) {
    if amount >= 0 {
        b.balance = amount
    }
}

Prawdziwa moc metod ustawiających polega na dodawaniu walidacji lub logiki biznesowej. Zamiast pozwalać zewnętrznemu kodowi ustawiać dowolną wartość bezpośrednio, kontrolujesz, co jest dozwolone:

func (b *BankAccount) Deposit(amount int) bool {
    if amount <= 0 {
        return false
    }
    b.balance += amount
    return true
}

Ta metoda Deposit działa jak wyspecjalizowany setter, który wymusza zasady: wpłaty nie mogą być ujemne. Kod zewnętrzny musi korzystać z Twoich metod, co zapewnia, że struktura zawsze pozostaje w prawidłowym stanie. Tak działa enkapsulacja: ukrywanie danych przy jednoczesnym udostępnianiu kontrolowanego zachowania.

challenge icon

Wyzwanie

Łatwy

Zbudujmy konwerter temperatury, który pokazuje prawidłowe hermetyzowanie za pomocą metod pobierających i ustawiających. Utworzysz strukturę przechowującą temperaturę wewnętrznie w stopniach Celsjusza, ale udostępniającą kontrolowany dostęp za pomocą metod z walidacją.

Rozmieścisz kod w dwóch plikach:

  • temperature.go: Utwórz strukturę Temperature z nieeksportowanym polem celsius (float64). Zaimplementuj następujące metody:
    • Celsius() - getter zwracający aktualną temperaturę w stopniach Celsjusza
    • SetCelsius(value float64) - setter, który akceptuje tylko wartości równe zeru absolutnemu (-273.15) lub wyższe. Jeśli wartość jest niższa od tego progu, temperatura powinna pozostać bez zmian.
    • Fahrenheit() - zwraca temperaturę przeliczoną na stopnie Fahrenheita za pomocą wzoru: (celsius * 9/5) + 32
    • SetFahrenheit(value float64) - przelicza wartość wejściową ze stopni Fahrenheita na Celsjusza i zapisuje ją, ale tylko wtedy, gdy wynikowa wartość w stopniach Celsjusza jest równa -273.15 lub wyższa
    Dodaj też konstruktor NewTemperature(celsius float64) *Temperature, który tworzy temperaturę z podaną wartością początkową (załóż, że konstruktor otrzymuje prawidłowe dane wejściowe).
  • main.go: Odczytaj wartości temperatury z danych wejściowych i pokaż działanie metod pobierających i ustawiających. Utwórz temperaturę, wyświetl jej wartości w obu jednostkach, a następnie spróbuj ustawić nowe wartości i pokaż wyniki.

Podane zostaną następujące dane wejściowe:

  • Wiersz 1: Początkowa wartość w stopniach Celsjusza
  • Wiersz 2: Nowa wartość w stopniach Celsjusza do ustawienia
  • Wiersz 3: Nowa wartość w stopniach Fahrenheita do ustawienia

Formatuj wszystkie wyświetlane temperatury z dokładnością do dwóch miejsc po przecinku. Wypisz następującą sekwencję:

  1. Po utworzeniu: C: [celsius] F: [fahrenheit]
  2. Po ustawieniu temperatury w stopniach Celsjusza: C: [celsius] F: [fahrenheit]
  3. Po ustawieniu temperatury w stopniach Fahrenheita: C: [celsius] F: [fahrenheit]

Na przykład dla wartości 25, -300 i 212 wynik powinien wyglądać tak:

C: 25.00 F: 77.00
C: 25.00 F: 77.00
C: 100.00 F: 212.00

Zauważ, że drugi wiersz pokazuje niezmienione wartości, ponieważ -300 jest poniżej zera absolutnego, więc setter odrzucił tę wartość. Trzeci wiersz pokazuje temperaturę po pomyślnym ustawieniu 212°F (co odpowiada 100°C). Na tym polega siła setterów. Egzekwują reguły, które zapewniają prawidłowość danych.

Spróbuj swoich sił

package main

import (
	"fmt"
)

func main() {
	// Odczytaj wartości wejściowe
	var initialCelsius float64
	var newCelsius float64
	var newFahrenheit float64
	fmt.Scanln(&initialCelsius)
	fmt.Scanln(&newCelsius)
	fmt.Scanln(&newFahrenheit)

	// TODO: Utwórz nowy obiekt Temperature za pomocą konstruktora

	// TODO: Wypisz wartości początkowe w formacie "C: [celsius] F: [fahrenheit]" z dokładnością do 2 miejsc po przecinku

	// TODO: Spróbuj ustawić nową wartość Celsius i wypisz wynik

	// TODO: Spróbuj ustawić nową wartość Fahrenheit i wypisz wynik
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Go online