package gotowe.p12_dziedziczenie.a_podstawy;

public class Polimorfizm2 {
    public static void main(String[] args) {
        Osoba osoba = new Osoba("Ala", "Kowalska", 30);
        Student student = new Student("Adam", "Abacki", 20, "prawo", 1);

        System.out.println(osoba);
        System.out.println(student);
        System.out.println();

        // 1) Podklasa może nie zmieniać metody z nadklasy - wtedy ta metoda jest "dziedziczona" i działa ta sama implementacja
        System.out.println(student.pelnoletnia());

        // 2) Podklasa może dodać zupełnie nowe metody
        student.dodajOcene(3);
        student.dodajOcene(4);
        student.dodajOcene(5);
        student.dodajOcene(5);

        System.out.println(student.sredniaOcen());
        // System.out.println(osoba.sredniaOcen());
        System.out.println();

        // 3) podklasa może też nadpisać (OVERRIDE) metodę, która istniała w nadklasie
        // wtedy gdy metoda zostanie wywołana na obiekcie podklasy, zadziała jej zmieniona wersja
        System.out.print("  osoba.przedstawSie(): ");
        osoba.przedstawSie();

        System.out.print("student.przedstawSie(): ");
        student.przedstawSie();
        System.out.println();

        // Java użyje wersji metody z podklasy także wtedy, gdy obiekt podklasy (Student)
        // będzie wpisany na zmienną typu nadklasa (Osoba):
        Osoba x;

        x = osoba;
        x.przedstawSie();

        x = student;
        x.przedstawSie();
        // bo w języku Java metody instancyjne są zawsze "wirtualne" (terminologia języka C++)

        // Zauważmy, że x.przedstawSie() wypisuje informację o kierunku,
        // ale sami bezpośrednio tej informacji nie odczytamy ze zmiennej x, bo jest ona typu Osoba
        // System.out.println(x.kierunek);

        System.out.println();

        // Wpisywanie studenta do zmiennej Osoba x jest nienaturalne.
        // Ale do podobnej sytuacji może dojść w zupełnie naturalny sposób.
        // 1) Kolekcja może zawierać obiekty różnych klas:
        Osoba[] osoby = {
                new Osoba("Ala", "Kowalska", 30),
                new Student("Adam", "Abacki", 20, "prawo", 1),
                new Pracownik("Jan", "Kowalski", 50, "kierowca", 4321),
        };

        // Wtedy gdy przeglądamy zawartość w pętli element kolekcji widzimy jako obiekt nadklasy (Osoba)
        for(Osoba o: osoby) {
            o.przedstawSie();
        }
        System.out.println();

        System.out.println("=========================");
        System.out.println("Idziemy do urzędu...");
        Urzad urzadMiasta = new Urzad();
        // Do urzędu jako Osoba może pójść zwykła Osoba, może też pójść Student...
        urzadMiasta.zalatwSprawe(osoba);
        urzadMiasta.zalatwSprawe(student);

        for(Osoba o: osoby) {
            urzadMiasta.zalatwSprawe(o);
        }
    }
}
