# Anonymous Class https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html 前面我們寫過一些interface, abstract class, 並且有個子類別繼承他們, 但是每次我們要建立一種介面實作, 或是抽象類別的子類, 就要建立一個class, 有時候只是希望一次性使用, 就會很麻煩。 所以我們可以不直接寫子類別, 直接new 一個interface/abstract class, 並且要實作方法。 寫法: ```new InterfaceOrAbstractClass(constructor param) {declaration};``` Example: 下面範例有三種, Printer class, IPrinter interface, PrinterAbstract abstract class 並且寫了個別的實作方式。 ```java class Printer { public void print(String s) { System.out.println(s); } } interface IPrinter { void print(String s); } class PrinterAbstract { public abstract void print(String s); } // ---------- in Main.java ---------- public class Main { public static void main(String[] args) { Printer v = new Printer() { @Override public void print(String s) { System.out.print("Class : " + s); } }; v3.print("Hello"); // Class : Hello IPrinter v2 = new IPrinter() { @Override public void print(String s) { System.out.print("Interface : " + s); } }; v3.print("Hello"); // Interface : Hello PrinterAbstract v3 = new PrinterAbstract() { @Override public void print(String s) { System.out.print("Abstract Class : " + s); } }; v3.print("Hello"); // Abstract Class : Hello } } ``` 總之class, abstract class, interface寫法都一樣。 # Lambda https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html 如果Interface 的non-static方法只有一個 我們可以把傳統的Interface Anoymous Class改寫成: `(param) -> statement` ```java= interface MathFunction { void run(int x,int y); } public class Main { public static void main(String[] args) { // 原本寫法 MathFunction sum = new MathFunction() { @Override public void run(int x, int y) { System.out.println(x + y); } }; sum.run(10, 20); // 30 MathFunction multiply = (x, y) -> { int result = x * y; System.out.println(result); }; multiply.run(10, 20); // 200 MathFunction subtract = (x, y) -> System.out.println(x - y); subtract.run(20, 10); // 10 } } ``` --- 如果param只有一個的話可以省去小括號 ```java= interface MathFunction { void run(int x); } public class Main { public static void main(String[] args) { MathFunction pow = x -> System.out.println(x * x); pow.run(10,20); //200 } } ``` <br> ### Lambda with return value 如果lambda有return值: 有幾種寫法: ``` (param) -> <return value> ``` ``` (param) -> { ... return xxx; } ``` ```java= interface MathFunction { int run(int x,int y); } public class Main { public static void main(String[] args) { MathFunction sum = new MathFunction() { @Override public int run(int x,int y) { return x + y; } }; System.out.println(sum.run(10,20))); //30 MathFunction multiply = (x,y) -> { int result = x * y; return result; }; System.out.println(multiply.run(10,20)); //200 //x * y is the return value itself. MathFunction subtract = (x,y) -> x - y; System.out.println(subtract.run(20, 10)); // 10 } } ``` ### Method Reference https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html - static method `ClassName::staticMethodName` - non-static method `object::instanceMethodName` - constructor `ClassName::new` 如果Lambda的效果如同呼叫一個方法/建構子, 可以用該方法的Method Reference代替。 ```java class Methods { public static int sum(int x, int y) { return x + y; } } class Test { public void sum(int x, int y) { return x + y; } } ``` --- 像是這個加法 ```java (x, y) -> x + y; ``` - 可以寫成 ```java (x, y) -> Methods.sum(x, y) Method::sum ``` - 如果是非靜態方法, 可以寫成 ```java Test obj = // ... (x, y) -> obj.sum(x, y) obj::sum ``` --- 如果是呼叫建構子 ```java (x, y) -> new Point(x, y); ``` 可以寫成 ```java Point::new ``` --- 哪邊會用到這鬼東西? 最常見的應該是foreach,在許多Collections都會用到 ```java= List<String> list = new ArrayList<>(); list.add("hello1"); list.add("hello2"); list.add("hello3"); for(String s : list) System.out.println(s); list.forEach(s -> System.out.println(s)); list.forEach(System.out::println); ```