Menu
Coddy logo textTech

Pola eksportowane i nieeksportowane

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

W Go enkapsulacja na poziomie struktury jest kontrolowana przez wielkość liter w nazwach pól. Ta prosta zasada określa, czy można uzyskać dostęp do pól spoza pakietu, w którym zdefiniowano strukturę.

Pola zaczynające się od wielkiej litery są eksportowane: dostępne z każdego pakietu. Pola zaczynające się od małej litery są nieeksportowane: dostępne tylko w obrębie tego samego pakietu:

// W pakiecie "user"
type User struct {
    Name     string  // Eksportowane – dostępne wszędzie
    Email    string  // Eksportowane – dostępne wszędzie
    password string  // Nieeksportowane – dostępne tylko w pakiecie "user"
    age      int     // Nieeksportowane – dostępne tylko w pakiecie "user"
}

Gdy inny pakiet importuje i używa tej struktury, może korzystać tylko z eksportowanych pól:

// W pakiecie "main"
import "user"

func main() {
    u := user.User{
        Name:  "Alice",      // działa
        Email: "a@mail.com", // działa
        // password: "secret", // błąd kompilacji: nieznane pole
    }
    
    fmt.Println(u.Name)     // działa
    // fmt.Println(u.password) // błąd kompilacji: nie można odwołać się do niewyeksportowanego pola
}

Ten mechanizm chroni poufne dane i wewnętrzne szczegóły implementacji. Pola password nie można odczytać ani zmodyfikować bezpośrednio spoza pakietu, co zmusza pozostały kod do korzystania z metod, które udostępniasz. To podejście Go do ukrywania danych: podstawowej zasady enkapsulacji w programowaniu obiektowym.

challenge icon

Wyzwanie

Łatwy

Stwórzmy system konta bankowego, który pokazuje hermetyzację za pomocą pól eksportowanych i nieeksportowanych. Utworzysz pakiet, który chroni wrażliwe dane finansowe, jednocześnie udostępniając bezpieczne informacje publiczne.

Rozmieścisz swój kod w dwóch plikach:

  • account.go: Utwórz strukturę BankAccount w pakiecie main, która modeluje rzeczywiste konto bankowe z odpowiednią ochroną danych:
    • HolderName (eksportowane) — imię i nazwisko posiadacza konta, które można bezpiecznie wyświetlać publicznie
    • AccountType (eksportowane) — typ konta (np. "Savings", "Checking")
    • balance (nieeksportowane) — rzeczywiste saldo, które powinno być chronione
    • pin (nieeksportowane) — PIN do konta, dane o wysokim stopniu poufności
    Dodaj funkcję konstruktora NewBankAccount, która przyjmuje imię i nazwisko posiadacza konta, typ konta, saldo początkowe i PIN, a następnie zwraca wskaźnik do nowej struktury BankAccount. Dodaj też metodę GetPublicInfo() string, która zwraca tekst w formacie: Account: [HolderName] ([AccountType])
  • main.go: Wczytaj dane konta z wejścia, utwórz BankAccount za pomocą konstruktora i pokaż działanie hermetyzacji. Wyświetl informacje publiczne za pomocą metody, a następnie uzyskaj bezpośredni dostęp do każdego eksportowanego pola i wyświetl je w osobnych wierszach. Pola nieeksportowane (balance i pin) są chronione. Możesz ustawić je tylko za pomocą konstruktora.

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

  • Wiersz 1: Imię i nazwisko posiadacza konta
  • Wiersz 2: Typ konta
  • Wiersz 3: Saldo początkowe (jako liczba zmiennoprzecinkowa)
  • Wiersz 4: Kod PIN

Na przykład dla danych Alice Johnson, Savings, 5000.50 i 1234 wynik powinien wyglądać następująco:

Account: Alice Johnson (Savings)
Holder: Alice Johnson
Type: Savings

Zwróć uwagę, że saldo i PIN nigdy nie pojawiają się na wyjściu: są bezpiecznie ukryte wewnątrz struktury i dostępne tylko w obrębie pakietu. To właśnie działanie hermetyzacji: wrażliwe dane są chronione, a informacje publiczne pozostają dostępne.

Spróbuj swoich sił

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Wczytaj imię i nazwisko posiadacza konta
	holderName, _ := reader.ReadString('\n')
	holderName = strings.TrimSpace(holderName)

	// Wczytaj typ konta
	accountType, _ := reader.ReadString('\n')
	accountType = strings.TrimSpace(accountType)

	// Wczytaj saldo początkowe
	balanceStr, _ := reader.ReadString('\n')
	balanceStr = strings.TrimSpace(balanceStr)
	balance, _ := strconv.ParseFloat(balanceStr, 64)

	// Wczytaj PIN
	pinStr, _ := reader.ReadString('\n')
	pin := strings.TrimSpace(pinStr)

	// TODO: Utwórz nowy BankAccount za pomocą konstruktora
	// account := NewBankAccount(...)

	// TODO: Wyświetl informacje publiczne za pomocą metody GetPublicInfo()

	// TODO: Wyświetl imię i nazwisko posiadacza, odwołując się bezpośrednio do eksportowanego pola
	// fmt.Println("Holder:", ...)

	// TODO: Wyświetl typ konta, odwołując się bezpośrednio do eksportowanego pola
	// fmt.Println("Type:", ...)

	// Uwaga: balance i pin nie są eksportowane — nie można uzyskać do nich bezpośredniego dostępu w tym miejscu
	// Są bezpiecznie hermetyzowane w strukturze

	_ = balance // Usuń tę linię, gdy użyjesz balance
	_ = pin     // Usuń tę linię, gdy użyjesz pin
}
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