Java 8 相比于Java 7 推出了幾大特色(features)(接口默認方法)default methods in interface, (接口靜態方法)static method in interface, 函數編程(functional programming), lamda expression, stream API.

這里首先介紹以下默認接口方法


1。什么是默認接口方法

java 8 允許在接口定義并編寫實現方法。例子:

interface?Collection{void?add();void?remove();//new?feature?in?java?8?//default?methoddefault?void?put(){System.out.println("put?the?key?in");}
}

由例子可以看出,java 8 添加新的關鍵字 default 用來實現在接口定義并實現一個方法。


2。 為什么需要默認接口方法

默認接口方法的語法很簡單, 但是java 8 為何需要引入這個新的概念卻大有文章。

這里我舉一個現實的例子, 現在我們需要向一個叫collection的接口添加一個新的方法,并且所有實現這個接口的類都可以調用這個方法。 這個在java 7 是可以實現的不過需要向每個實現這個接口的類重新重寫override 這個方法。 這樣其實很不好, 因為這里需要修改每個實現接口類的方法。 不然沒辦法通過編譯。

但是如果允許接口實現方法即(默認接口方法)可以很好解決這個問題。廢話不多說先上例子:

interface?Collection{void?add();void?remove();//new?requirement:?project?need?add?a?new?method//but?we?can't?overrided?the?method?in?each?implements?classes//default?method?is?to?solve?this?problemsdefault?void?put(){System.out.println("put?the?key?in");}
}class?List?implements?Collection{@Overridepublic?void?add()?{//?TODO?Auto-generated?method?stub}@Overridepublic?void?remove()?{//?TODO?Auto-generated?method?stub}}public?class?WhyNeedDefault?{public?static?void?main(String[]?args)?{List?list?=?new?List();list.add();//now?list?have?new?method?putlist.put();}
}

?上面例子簡單的利用接口默認方法為所有實現collection 接口的類添加的一個新的put方法.并且list 類不需要任何代碼修改。最后list.put() 可以直接被調用。


3 使用default interface method 需要注意的一些細節

3.1 當一個類實現多個接口并且多個接口都有相同的方法

假設:IDefaultMethods, IRegular 接口都有一個叫做 void talk()的方法

java8編譯器會報錯 如果FianlClass2 不重寫override talk()方法

//error?will?show?if?IDM?and?IRr?has?the?same?method?define?unless?overrided?the?talk?method
public?class?FinalClass2?implements?IDefaultMethods,?IRegular{public?static?void?main(String[]?args)?{}@Overridepublic?void?move()?{//?TODO?Auto-generated?method?stub}@Overridepublic?void?fly()?{//?TODO?Auto-generated?method?stub}@Overridepublic?void?talk()?{//?TODO?Auto-generated?method?stubSystem.out.println("final?class?2?talk?method");}


3.2 當一個類繼承一個類并且實現多個接口。這個父類和多個接口都有相同的方法

假設:ClassA, IDefaultMethods, IRegular 接口都有一個叫做 void talk()的方法

編譯結果這個時候可能會另大家失望了,編譯器沒有報錯即使finalclass4 不重寫talk() 方法。

因為classA 會被優先調用talk()>接口方法talk()

//no?error?shows?even?FC4?not?overrided?the?talk?method
//error?only?happen?if?compiler?can't?figure?out?which?method?need?to?be?called
public?class?FinalClass4?extends?ClassA?implements?IDefaultMethods,IRegular{@Overridepublic?void?move()?{//?TODO?Auto-generated?method?stub}@Overridepublic?void?fly()?{//?TODO?Auto-generated?method?stub}public?static?void?main(String[]?args)?{FinalClass4?fc4?=?new?FinalClass4();fc4.talk();??//輸出classA?的talk?方法}