Java8 新特性(一)- 介面增強
本章目錄
- Part One:介面預設方法
- Part Two:介面靜態方法
隨著16年Android N的釋出,Google宣佈Android正式開始支援Java8。不過一直有點懶,拖啊拖,直到Java9已經出了不少日子了,才開始學Java8新特性~老實說,有點慚愧。
另外,Lambda表示式和方法引用越來越被大家熟悉使用,尤其是Rx全家桶裡,再不好好學,程式碼都快看不懂了,順道的把Java8的所有新特性也都研究一遍吧。
Part One:介面預設方法
從Java8開始,在介面中可以新增一個或者多個使用default關鍵字修飾的非抽象方法,就是介面的預設方法。預設方法可以讓我們的軟體介面增加新的方法,並且保證老版本的相容性。
在Java8中,官方提供的API裡就使用了預設方法,但是我們在呼叫這些API的時候,並沒有感覺到跟以前的使用有什麼不同之處,這就是預設方法的作用。例如, Iterator介面:
- 預設方法的簡單實現
暫時不考慮一些額外的干擾因素,只是實現簡單的預設方法並不複雜,程式碼如下:
package cn.tmooc.tarena;
interface Person{
void eat();
void sleep();
/**
* 介面的預設方法,獲取人體的BMI指數
* @param height 米
* @param weight 公斤
* @return
*/
default float getBMI(float height, float weight) {
return weight / (float)Math.pow(height, 2);
}
}
class Student implements Person{
@Override
public void eat() {
System.out.println("學生去食堂吃飯");
}
@Override
public void sleep() {
System.out.println("學生去宿舍睡覺");
}
}
class Parent implements Person{
@Override
public void eat() {
System.out.println("家長回家吃飯");
}
@Override
public void sleep() {
System.out.println("家長回家睡覺");
}
}
public class InterfaceSample {
public static void main(String[] args) {
Person student = new Student();
student.eat();
student.sleep();
//呼叫介面的預設方法
float bmi = student.getBMI(1.83F, 100);
System.out.println("student的BMI指數 = " + bmi);
System.out.println("==============================");
Person mom = new Parent();
mom.eat();
mom.sleep();
System.out.println("mom的BMI指數 = " + mom.getBMI(1.60F, 50));
}
}
其中,Person是一個人類介面,定義了兩個普通方法和一個預設方法。而它的子類Student和Parent都必須實現普通方法,預設方法自動繼承了,可直接呼叫。
最後的結果如下:
預設方法的修改(增刪改)都不會影響到已經存在的介面的編譯,但是使用之前一定要仔細考慮是不是真的需要使用預設方法,因為在層級很複雜的情況下很容易引起模糊不清甚至變異錯誤。
- 多重繼承的衝突原則
由於一個方法可以從不同的介面引入,那麼衝突就不可避免的,最簡單的兩條是
2.1 子介面的優先順序更高,即如果介面之間有繼承關係,子介面的預設方法會覆蓋父介面的預設方法;
2.2 類中的方法優先順序最高, 即實現類中重寫了預設方法,那麼以實現類為主;
package cn.tmooc.tarena;
interface A {
default void hello() {
System.out.println("Hello from A!");
}
default void hi() {
System.out.println("Hi from A!");
}
}
interface B extends A {
default void hello() {
System.out.println("Hello from B!");
}
default void hi() {
System.out.println("Hi from B!");
}
}
public class InterfaceSample implements B, A {
@Override
public void hi() {
System.out.println("Hi from InterfaceSample!");
}
public static void main(String[] args) {
InterfaceSample sample = new InterfaceSample();
sample.hello(); //子介面的優先順序更高,所以結果為Hello from B!
sample.hi(); //類中的方法優先順序最高,所以結果為Hi from InterfaceSample!
}
}
2.3 如果兩個同級的介面,具有相同的方法,那麼需要顯示指定到底呼叫哪個方法。例如,兩個同級的介面都有hello方法
程式碼會報錯,解決方法就是讓類實現某一個介面的該方法,使其具有更高的優先順序即可。
-
預設方法不能重寫Object方法
例如我們重寫了toString方法,會報以下錯誤: - Java8中抽象類和介面的異同
相同點:
都是抽象型別的;
都可以有具體的實現方法;
都可以不需要實現類或者繼承者去實現所有方法;
不同點:
宣告時使用的關鍵字不同;
抽象類不可以多重繼承,介面可以;
抽象類和介面所反映出的設計理念不同。其實抽象類表示的是"is-a"關係,介面表示的是"like-a"關係;
介面中定義的變數預設是public static final 型,且必須給其初值,所以實現類中不能重新定義,也不能改變其值;抽象類中的變數可以是任意型別的,其值可以在子類中重新定義,也可以重新賦值。
Part Two:介面靜態方法
Java8為介面新增靜態方法後,可以把常用的工具方法直接寫在介面上,可以更好地組織程式碼,更易閱讀和使用。
例如,在官方的Comparator介面裡就提供了一個靜態比較方法:
寫法上和預設方法沒啥區別,就是修飾符不太一樣,這裡不再贅述了就。
相關文章
- Java8新特性探索之Stream介面Java
- java8 新特性之函式式介面Java函式
- Java8的新特性--函式式介面Java函式
- Java8新特性探索之函式式介面Java函式
- Java 16 新特性:instanceof增強Java
- JAVA8新特性Java
- Java8 新特性Java
- Java8 新特性,打破你對介面的認知Java
- Java8新特性(一)-Lambda表示式Java
- Java8新特性-四大核心函式式介面Java函式
- Java8新特性 - LambdaJava
- Java8的新特性Java
- JAVA8新特性用法Java
- ABAP 740新的OPEN SQL增強特性SQL
- C# 9 新特性 —— 增強的 foreachC#
- java8特性-函式式介面Java函式
- Java8新特性系列-LambdaJava
- Java8新特性之:OptionalJava
- Java8新特性--Stream APIJavaAPI
- Java8新特性實踐Java
- java8新特性stream流Java
- Java8 新特性詳解Java
- LightDB23.1新特性支援Oracle hint增強DB2Oracle
- C# 9 新特性 —— 增強的模式匹配C#模式
- 新特性介面
- ?Java8新特性之Optional類Java
- java8 新特性之方法引用Java
- java8 新特性之Optional 類Java
- Java8新特性之時間APIJavaAPI
- Java8新特性(1):Lambda表示式Java
- Java8常用的新特性總結Java
- java8 新特性之Lambda 表示式Java
- java8 新特性之預設方法Java
- Java8新特性都到碗裡來Java
- 【Java8新特性】還沒搞懂函式式介面?趕快過來看看吧!Java函式
- 深度解讀 MongoDB 最全面的增強版本 4.4 新特性MongoDB
- Java8 新特性 —— Stream 流式程式設計Java程式設計
- java8 新特性之日期時間 APIJavaAPI
- Java8新特性之日期-時間APIJavaAPI