1. 程式人生 > >Java8新特性default關鍵字,引出Java多繼承問題

Java8新特性default關鍵字,引出Java多繼承問題

概述

最近在看JDK集合的原始碼時,在Collection介面中發現了default關鍵字,並且驚奇的發現介面中的方法居然包含方法體,這頓時讓我產生興趣,為此我也稍微研究了一下default關鍵字。

很多同學都知道Java在創立之初就摒棄了C++多繼承的套路,因為它實在難以學習與使用,在Java的世界中類只能繼承一個父類,但是一個介面可以繼承多個介面,就比如這樣:

public interface A {
    void hello();
}

public interface B {
    void hello();
}

public interface C extends A,B {

}

但是Java8的新特性也使得Java也擁有了多繼承的問題,想要了解的小夥伴就繼續往下看吧。

 

引入default關鍵字

大家都知道Java中的介面都是抽象方法,也就是沒有方法體,但是從Java8開始,如果介面中的方法被default關鍵字修飾後就必須為其加上方法體。某個類在實現該介面時,就不會強制實現被default修飾的方法,因為在介面中已經寫好了方法體。從Java8開始,介面就開始類似於抽象類了,它們都可以含有普通方法和抽象方法了,唯一不同的就是一個類只能繼承一個抽象類,而一個類卻能實現多個介面。

default關鍵字示例:

public interface A {
	default void sayHello(){
		System.out.print("A.Hello");
	}
}

default關鍵字的意義:default關鍵字的意義,default的意思就是為介面方法提供預設的實現,它的最終目的就是減少子類實現介面的工作量,如果多個子類實現的某個介面方法,方法體都是一樣的,這就會導致後期維護上的困難,如果在介面中定義預設的實現,那麼既減少了子類實現的介面的工作量,也為後期的維護提供了方便(只需要更改介面中的預設實現即可)。

多繼承問題的引入

但是default關鍵字的出現也順帶為java帶來了多繼承的問題,我現在來舉一個栗子:

現有兩個介面,A和B,這兩個介面都有一個方法sayHello,並且都使用default關鍵字修飾後使其擁有了方法體,但是現在有介面C需要同時繼承A,B,程式碼如下:

public interface A {
	default void sayHello(){
		System.out.print("A.Hello");
	}
}

public interface B {
	default void sayHello(){
		System.out.print("B.Hello");
	}
}

public interface C extends A,B{
	
}

此時多繼承的問題就展現出來了,到底C介面是繼承A介面的sayHello方法,還是繼承B介面的sayHello方法,這也就是Java多繼承的源頭,允許介面有方法體,並且介面之間可以多繼承。(上面程式碼由於有多繼承問題,編譯會報錯!!)

 

多繼承問題的解決

Java給出的解決方案就是:在出現多繼承問題的時候必須手動覆寫衝突方法,這種方式可謂是簡單出爆,但很好理解。手動覆寫後編譯器就不糾結到底繼承哪個父類的方法了,也就解決了多繼承問題。

子介面在手動覆寫父介面方法時可以手動呼叫衝突方法,呼叫格式如下:

public interface A {
	default void sayHello(){
		System.out.print("A.Hello");
	}
}

public interface B {
	default void sayHello(){
		System.out.print("B.Hello");
	}
}

public interface C extends A,B{
	@Override
	default void sayHello() {
		A.super.sayHello();
	}
}