package gotowe.p10_klasy_podstawy;

// Przy definicjach w tym pakiecie nie ma zadeklarowanego poziomu widoczności (public/private).
// W tej sytuacji obowiązuje widoczność domyślna=pakietowa.
class Osoba {
    // Zmienna definiowana na poziomie klasy (a nie w metodach) jest określana jako:
    // pole (field), atrybut (attribute) lub zmienna instancyjna (instance variable).
    // Wartości takich zmiennych (nie-statycznych) przechowywane są oddzielnie w każdym obiekcie.
    // W tej wersji klas pozostawiamy pola na poziomie widoczności pakietowej. W praktyce Javy najczęściej pola są prywatne.
    String imie, nazwisko;
    int wiek;

    // Zmienne oznaczone static to: zmienne statyczne / pola statyczne / atrybuty statyczne.
    // Wartość jest przechowywana w jednym egzemplarzu w klasie (a nie obiekcie).
    // Wszystkie obiekty mają dostęp do jednej, wspólnej wartości zmiennej statycznej.
    // Dodatkowo oznaczenie final i wpisanie konkretnej wartości powoduje, że jest to stała (i tak jest traktowana przez kompilator).
    static final int WIEK_PELNOLETNIOSCI = 18;
    
    // Konstruktor bezargumentowy, nazywany także "konstruktor domyślny" / default constructor.
    // Zostałby automatycznie utworzony, gdyby w klasie nie było innych konstruktorów, ale jeśli są, to musi być zdefiniowany jawnie.
    Osoba() {
    }

    // Dosyć często (ale nie zawsze) definiuje się konstruktor, który inicjalizuje wszystkie pola przekazanymi wartościami.
    Osoba(String imie, String nazwisko, int wiek) {
        this.imie = imie;
        this.nazwisko = nazwisko;
        this.wiek = wiek;
    }

    // Metoda ("nie-statyczna", czyli "instancyjna") to czynność, którą "potrafi" wykonać obiekt.
    // Inaczej mówiąc, to funkcja, która jest wywoływana i wykonuje się w kontekście określonego obiektu.
    void przedstawSie() {
        System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + wiek + " lat.");
    }

    // Metoda może zwracać wynik. Bardzo często wynik zależy od aktualnej wartości pól w obiekcie.
    boolean pelnoletnia() {
        return wiek >= WIEK_PELNOLETNIOSCI;
    }

    // Metoda może zmieniać stan obiektu.
    void postarzejSie() {
        wiek += 1;
    }
}
