Java 8新增了default方法,它可以在接口添加新功能特性,而且還不影響接口的實現類。下面我們通過例子來說明這一點。
public class MyClass implements InterfaceA {
public static void main(String[] args){
}
@Override
public void saySomething() {
// TODO Auto-generated method stub
}
}
interface InterfaceA{
public void saySomething();
}
上面的代碼顯示了MyClass類實現了InterfacesA接口的saySomething()方法。現在我們為InterfacesA接口新增一個sayHi()方法。這麼做的話,MyClass類是無法通過編譯的,除非我們提供了sayHi()的實現方法。
Default方法是非常有用的,通過在接口定義的方法的訪問修飾符前加上關鍵字default,那麼實現類就無需提供該方法的實現了。比如:
public class MyClass implements InterfaceA {
public static void main(String[] args){
}
@Override
public void saySomething() {
// TODO Auto-generated method stub
}
}
interface InterfaceA{
public void saySomething();
default public void sayHi(){
System.out.println("Hi");
}
}
要注意,我們必須提供所有的default方法的實現。因此,default方法使我們的代碼更加靈活,在接口中也可以寫方法實現了。實現的方法會作為默認的方法實現。
那麼,多接口存在沖突該怎麼辦?
由於Java類可以實現多個接口,那麼就可能存在這樣的情況:兩個或多個接口都有一個同名的default接口方法,從而造成沖突。因為Java虛擬機在程序運行時,並不清楚你要使用哪一個default方法。這會導致編譯錯誤。
讓我們來看看下面的例子。
public class MyClass implements InterfaceA, InterfaceB {
public static void main(String[] args){
MyClass mc = new MyClass();
mc.sayHi();
}
@Override
public void saySomething() {
// TODO Auto-generated method stub
}
}
interface InterfaceA{
public void saySomething();
default public void sayHi(){
System.out.println("Hi from InterfaceA");
}
}
interface InterfaceB{
default public void sayHi(){
System.out.println("Hi from InterfaceB");
}
}
它是通不過編譯的,會報以下錯誤:
“Duplicate default methods named sayHi with the parameters () and () are inherited from the types InterfaceB and InterfaceA.”
除非在MyClass類中重寫了sayHi()方法:
public class MyClass implements InterfaceA, InterfaceB {
public static void main(String[] args){
MyClass mc = new MyClass();
mc.sayHi();
}
@Override
public void saySomething() {
// TODO Auto-generated method stub
}
@Override
public void sayHi(){
System.out.println("implemetation of sayHi() in MyClass");
}
}
interface InterfaceA{
public void saySomething();
default public void sayHi(){
System.out.println("Hi from InterfaceA");
}
}
interface InterfaceB{
default public void sayHi(){
System.out.println("Hi from InterfaceB");
}
}
如果想指定調用哪一個接口的sayHi()方法,我們可以這麼做:
public class MyClass implements InterfaceA, InterfaceB {
public static void main(String[] args){
MyClass mc = new MyClass();
mc.sayHi();
}
@Override
public void saySomething() {
// TODO Auto-generated method stub
}
@Override
public void sayHi(){
InterfaceA.super.sayHi();
}
}
interface InterfaceA{
public void saySomething();
default public void sayHi(){
System.out.println("Hi from InterfaceA");
}
}
interface InterfaceB{
default public void sayHi(){
System.out.println("Hi from InterfaceB");
}
}
答案是不是很簡單呢?