package p13_lambdy;

public class PrzykladyNiefunkcyjne {

    public static void main(String[] args) {
        // Jeśli mam zdefiniowaną klasę zgodną z interfejsem, to po prostu tworzę obiekt tej klasy.
        // Mogę wpisać do zmiennej typu zgodnego z klasą:
        TradycyjnaImplementacjaInterfejsu obiekt1 = new TradycyjnaImplementacjaInterfejsu();
        
        // mając obiekt, mogę wywołać jego metody:
        System.out.println(obiekt1);
        System.out.println(obiekt1.oblicz(3));
        System.out.println(obiekt1.akuku());
        System.out.println();
        
        // Tak stworzony obiekt mogę też wpisać do zmiennej typu interfejsowego:
        FunkcjaLiczbowa obiekt2 = new TradycyjnaImplementacjaInterfejsu();
        System.out.println(obiekt2);
        System.out.println(obiekt2.oblicz(4));
        // W tej sytuacji można wywoływać tylko te metody, które są zadeklarowane w interfejsie (plus equals, hashCode i toString)
        // System.out.println(obiekt2.akuku());
        // można po jawnym zrzutowaniu:
        System.out.println(((TradycyjnaImplementacjaInterfejsu)obiekt2).akuku());
        System.out.println();
        
        // Od początków Javy dostępny jest taki skrótowy sposób tworzenia obiektu, który jest zgodny z interfejsem.
        // Nazywa się to "klasa anonimowa":
        FunkcjaLiczbowa obiekt3 = new FunkcjaLiczbowa() {
            public double oblicz(double x) {
                return x*x*x;
            }
        };
        
        System.out.println(obiekt3);
        System.out.println(obiekt3.oblicz(3));
    }

}
