/** Lambda expressions and functional interfaces.
 * @author Jaanus
 * @since 1.8
 */
public class J8example4 {

  @FunctionalInterface
  interface Talker<X> {
    void talk (X x);

    default void log (X x) {
      System.out.println ("logged by log in Talker interface: " + x);
      newlog (x.toString());
    }

    static void newlog (String s) {
      System.out.println ("logged by newlog in Talker interface: " + s);
    }
  }

  static class MyTalker1<X> implements Talker<X> {
    @Override
    public void talk (X x) {
      System.out.println ("talk from MyTalker1: " + x);
    }

    @Override
    public void log (X x) {
      System.out.println ("logged by log in Mytalker1: " + x);
      System.out.println ("also call to newlog by log in MyTalker1:");
      Talker.newlog (x.toString());
    }
  }

  static class MyTalker2<X> implements Talker<X> {
    @Override
    public void talk (X x) {
      System.out.println ("talk from MyTalker2: " + x);
    }
  }

  public static void main (String[] args) {
    Talker<Integer> italk = i -> System.out.println ("int " + i);
    Talker<Double> dtalk = d -> System.out.println ("double " + d);
    italk.talk (45);      // int 45
    dtalk.talk (Math.PI); // double pi
    MyTalker1<Integer> myitalk1 = new MyTalker1<Integer>();
    myitalk1.talk (2014); // from class
    myitalk1.log (1022);  // log from class contains static newlog from interface 
    MyTalker2<Integer> myitalk2 = new MyTalker2<Integer>();
    myitalk2.talk (2015); // from class
    myitalk2.log (1023);  // from interface contains static newlog
  }

}
