1、接口
接口的好處:(接口的作用是將所有對象(實現類)共同的部分放置在一起,減少重複定義)
通用性(無差別對待)
隔離性(隔離無關功能)
基本定義格式:
public interface 接口名稱{
語句塊:組成部分:抽象方法、常量、默認方法(java8)、靜態方法(java8)、私有方法(java9)
}
<1>抽象方法定義(LittleBaby)
抽象方法對實現類有一定的約束力,但不是完全約束,對於不同實現類在同一約束下的行爲只要符合抽象方法的統一約束即可。
public abstract 返回值類型 方法名稱(參數類型 參數名稱);
注意事項:(1)接口中的抽象方法,修飾如果寫必須是public abstract
(2)接口中的抽象方法,修飾符可以省略不寫,默認就是:public abstract
(3)接口中的抽象方法只有方法頭,沒有方法體(即{}及其中的內容)
package xwg.Eric.study.port;
public interface LittleBaby {
public abstract String xue();
public abstract String xiao();
public abstract String lei();
}
<2>接口實現類的定義(LittleBaby)(爲接口類定義方法體,實現功能)
如果要使用定的義好接口,必須有一個接口的“實現類”。
定義實現類格式爲:
public class 實現類名稱 implements 接口名稱 {
//覆蓋重寫所有的抽象方法
/*覆蓋重寫(Override)的步驟:
*(1)將接口當中的抽象方法複製粘貼
*(2)去掉abstract關鍵字
*(3)寫上大括號方法體
*/
}
package xwg.Eric.study.port;
public class LittelBabyImpl implements LittleBaby {
public String xue() {
System.out.println("小寶貝");
return null;
}
public String xiao() {
return null;
}
public String lei() {
return null;
}
public void play() {
}
}
<3>接口與實現類的基本使用(UseBaby)
使用方法:(1)創建:接口名稱 引用名 = new 實現類名稱();
(2)調用:引用名.抽象方法名(參數)
注意事項:(1)左邊是接口口類型,只能調用接中定義的抽象方法,不能調用右側實現類當中特有的方法(接口隔離)
(2)當調用接口當中的抽象方法時,真正進行運行的是右側new的時候類的具體方法內容。
(3)調用的時候看左邊,運行的時候看右邊。LittleBaby baby = new LittelBabyImpl();
package xwg.Eric.study.port;
public class UseBaby {
public static void main(String[] args) {
LittleBaby baby = new LittelBabyImpl();
baby.xue();
baby.xiao();
baby.lei();
baby.play();//不能調用接口中沒有定義的抽象方法
}
}
2、面向接口的編程
使用接口作爲左側類型的優點:屏蔽右側的個性特有內容,達到隔離、統一的目的
面向接口編程:如果使用功能,接口就已經可以滿足,不在乎具體的類是誰,只在乎接口即可
3、λ(Lambda)表達式(函數式編程)
一般建議使用接口名後加(大寫i)Impl作爲實現類
package xwg.Eric.study.port;
public interface CalculaterIterface {
public abstract double add(double a, double b);
}
package xwg.Eric.study.port;
import java.util.Scanner;
public class UseCalculaterInterface {
public static void main(String[] args) {
method((a, b) -> a + b);//λ表達式
}
public static void method(CalculaterIterface cal) {
Scanner sc = new Scanner(System.in);
System.out.print("請輸入a:");
double a = sc.nextFloat();
System.out.print("請輸入b:");
double b = sc.nextFloat();
double result = cal.add(a, b);
System.out.print("結 果:" + result);
sc.close();
}
}
λ表達式:method((a,b) -> a + b)
method方法需要一個Calculater接口類型的參數,λ表達式就是充當Calculater接口類型的參數;
λ前面的小括號就是接口抽象方法的小括號,箭頭代表拿着小括號的動作做什麼事情,是一個指向動作,箭頭後面表示拿到參數後執行的操作是什麼。
lambda表達式的語義本身就代表需要執行的操作是什麼,沒有對象的概念在裏面,更加簡單直觀。
<1>λ表達式標準格式
使用條件:需要存在函數式的推斷環境
檢查方法:(1)通過方法的參數類型來確定那個是函數式接口(2)通過賦值來確定那個是函數式接口
標準格式:抽象方法:public abstract int sum (int a , int b);
lambda的標準格式:(int a ,int b) -> { return a + b; }
lambda表達式的返回值類型要與定義接口的返回值類型相同
<2>λ表達式簡便格式
在lambda表達式中凡是可以推導的都可以省略
(1)表達式中的參數類型可以省略不寫
(2)如果參數只有一個,那麼小括號可以省略
(3)如果語句只有一個,大括號和return也可以省略
package xwg.Eric.study.port;
import java.util.Scanner;
public class UseCalculaterInterface {
public static void main(String[] args) {
method((double a, double b) -> { return a + b;} );
method((a, b) -> a + b);//最簡格式
}
public static void method(CalculaterIterface cal) {
Scanner sc = new Scanner(System.in);
System.out.print("請輸入a:");
double a = sc.nextFloat();
System.out.print("請輸入b:");
double b = sc.nextFloat();
double result = cal.add(a, b);
System.out.print("結 果:" + result);
sc.close();
}
}
<3>Lambda的上下文推斷
(1)調用方法的時候,參數類型是函數式接口類型,所以Lambda可以推斷出是哪個接口
(2)根據賦值語句的左側的類型來進行Lambda上下文推斷
Lambda表達式不能直接寫,需要有賦值語句,因爲沒有上下文環境,其無法推斷是哪個函數式接口。
4、函數式接口
java當中使用Lambda表達式的前提是:必須有函數式接口
函數式接口:在定義接口中有且僅有一個抽象方法的接口。叫做函數式接口
檢測接口是不是函數式接口只需要在public interface前面加:@FunctionalIterface 即可
5、簡化λ表達式
對於λ表達式實現的功能,如果在某個類中已經定義,則會造成冗餘的現象,我們可以使用如下來簡化
格式:類名稱::方法名稱 //可實現與λ表達式相同的功能。