Java8的default方法詳解

chszs發表於2015-01-11
版權宣告:本文為博主chszs的原創文章,未經博主允許不得轉載。 https://blog.csdn.net/chszs/article/details/42612023

Java 8的default方法詳解

作者:chszs,轉載需註明。部落格主頁:http://blog.csdn.net/chszs

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");
	}
}

答案是不是很簡單呢?


相關文章