package p25_lambdy;

public class Przyklady {
    public static void main(String[] args) {
        double wynik;

        // Aby utworzyć obiekt, który jest zgodny z interfejsem, można
        // - od zawsze - stworzyć oddzielną klasę, które implementuje interfejs, a następnie obiekt tej klasy
        FunkcjaLiczbowa f1 = new NaszaImplementacjaInterfejsu();
        wynik = f1.oblicz(11);
        System.out.println(wynik);

        // - od Javy 1.2 - użyć notacji "klasa anonimowa"
        FunkcjaLiczbowa f2 = new FunkcjaLiczbowa() {
            public double oblicz(double x) {
                return x*x;
            }
        };
        wynik = f2.oblicz(2);
        System.out.println(wynik);

        // - od Javy 8 - użyć wyrażenia lambda
        FunkcjaLiczbowa f3 = x -> x*x;
        wynik = f3.oblicz(3);
        System.out.println(wynik);

        // skorzystajmy z metody zdfiniowanej jako default
        f3.wypisz(5);

        System.out.println("Obiekt f3: " + f3);
        if(f3 instanceof FunkcjaLiczbowa) {
            System.out.println("Jest instancją");
        }

        // Wyrażenia lambda mogą być bardziej rozbudowane.
        // Jeśli po prawej stronie wpisujemy {blok w klamerkach}
        // to wynik zwracamy normalnie za pomocą return
        FunkcjaLiczbowa f4 = (double arg) -> {
            if(arg < 0) {
                System.out.println("f4 dostało liczbę ujemną " + arg);
                return (-arg) * 100;
            } else {
                System.out.println("f4 dostało liczbę dodatnią " + arg);
                return arg + 50;
            }
        };

        wynik = f4.oblicz(-7);
        System.out.println(wynik);

        wynik = f4.oblicz(7);
        System.out.println(wynik);

        FunkcjaLiczbowa f5 = Math::sqrt;
        wynik = f5.oblicz(49);
        System.out.println(wynik);
    }
}
