Java介面和抽象類的區別

2019-10-16 22:23:33

抽象類和介面之間的區別是熱門的Java面試題。抽象類和介面是Java程式設計語言的核心部分,如何選擇介面或抽象類是每個架構師面臨的設計決策。

在前面的文章中,學習了有關java介面和抽象類。

在這篇文章中,我們將了解抽象類和介面之間的區別,以及何時應該在抽象類上使用介面,反之亦然。

抽象類和介面之間的區別主要體現在以下幾個方面

  • abstract關鍵字用於建立抽象類,它也可以與方法一起使用,而interface關鍵字用於建立介面,不能與方法一起使用。

  • 子類使用extends關鍵字來擴充套件抽象類,它們需要提供抽象類中所有宣告的方法的實現,除非子類也是一個抽象類而不需要實現。而子類使用implements關鍵字來實現介面,並且應該為所有宣告的方法提供實現。

  • 抽象類可以具有實現的方法,而介面提供絕對抽象,並且不能具有任何方法實現。請注意,從Java 8開始,可以在包含方法實現的介面中建立預設和靜態方法。

  • 抽象類可以有建構函式,但介面不能有建構函式。

  • 抽象類具有普通java類的所有功能,除了無法範例化它。可以使用abstract關鍵字來建立類抽象,但介面是完全不同的型別,並且只能有公共靜態最終常數和方法宣告。

  • 抽象類方法可以具有存取修飾符作為:publicprivateprotected,static但是介面方法是隱式公共和抽象的,我們不能使用任何其他存取修飾符和介面方法。

  • 子類只能擴充套件一個抽象類,但可以實現多個介面。

  • 抽象類可以擴充套件其他類並實現介面,但介面只能擴充套件其他介面。

  • 如果它有main()方法,可以執行一個抽象類。但是不能執行介面,因為介面不能有main方法實現。

  • 介面用於定義子類的契約,而抽象類也定義契約,但它可以為子類提供其他方法實現。

上面就是介面和抽象類之間的區別。

使用介面還是抽象類?

如何在介面或抽象類之間進行選擇以提供子類的契約是一個設計決策,取決於許多因素。讓我們看看何時使用介面,何時使用抽象類。

  • Java不支援多類級別繼承,因此每個類只能擴充套件一個超類。但是一個類可以實現多個介面。因此,大多數時候,介面是為類層次結構和契約提供基礎的不錯選擇。在介面方面編碼也是在java中編碼的最佳實踐之一。

  • 如果契約中有很多方法,那麼抽象類更有用,因為可以為所有子類共有的一些方法提供預設實現。此外,如果子類不需要實現特定的方法,它們可以避擴音供實現,但是在介面的情況下,子類必須為所有方法提供實現,即使它沒有用,並且實現只是空塊。

  • 如果基本契約不斷變化,那麼介面可能會導致問題,因為我們無法在不更改所有實現類的情況下向介面宣告其他方法,使用抽象類可以提供預設實現,並且只更改實際執行的實現類使用新方法。

使用抽象類和介面

大多數時候,使用介面和抽象類是設計系統的最佳方法,例如在JDK中java.util.List是一個包含很多方法的介面,所以有一個抽象類java.util.AbstractList,它為List介面的所有方法提供骨架實現,以便任何子類都可以擴充套件此類並僅實現所需的方法。

我們應該始終以介面作為基礎並定義每個子類應該實現的方法,然後如果有一些方法只應該實現某些子類,可以擴充套件基介面並使用這些方法建立一個新介面。子類可以選擇在基本介面或子介面之間進行選擇,以根據其要求實現。如果方法的數量增長很多,那麼提供一個實現子介面的骨架抽象類並為子類提供在介面和抽象類之間進行選擇的靈活性並不是一個壞主意。

Java 8的介面變化

從Java 8開始,可以在介面中提供方法的實現。可以在介面中建立預設方法和靜態方法,並為它們提供實現。這彌補了抽象類和介面之間的差距,現在介面是要走的路,因為可以通過為新方法提供預設實現來進一步擴充套件它。