Java 中抽象類和介面的區別

抽象類別和介面之間的差異是一個流行的面試問題。抽象類別和介面是Java程式語言的核心部分。選擇介面或抽象類別是每個架構師面臨的設計決策。在我最近的文章中,我盡可能提供了有關Java介面抽象類別的詳細資訊。在這篇文章中,我們將了解抽象類別和介面之間的差異,以及何時應該選擇介面而不是抽象類別,反之亦然。

抽象類別與介面的差異

  1. 關鍵字abstract被用來創建一個抽象類別,它也可以用於方法,而interface關鍵字被用來創建介面,但它不能用於方法。
  2. 子類別使用extends關鍵字來擴展一個抽象類別,它們需要提供抽象類別中所有聲明方法的實現,除非子類別也是一個抽象類別;而子類別使用implements關鍵字來實現介面,並應提供介面中所有聲明方法的實現。
  3. 抽象類別可以有具體實現的方法,而介面提供絕對的抽象,不能有任何方法的實現。需要注意的是,從Java 8開始,我們可以在介面中創建包含方法實現的默認和靜態方法。
  4. 抽象類別可以有構造函數,但介面不能有構造函數。
  5. 抽象類別具有普通Java類別的所有功能,只是無法實例化。我們可以使用abstract關鍵字將類別設置為抽象,但介面是完全不同的類型,只能擁有公共靜態常量和方法聲明。
  6. 抽象類別的方法可以具有公共、私有、受保護、靜態等訪問修飾符,但介面方法默認為公共和抽象,不能使用其他訪問修飾符。
  7. A subclass can extend only one abstract class but it can implement multiple interfaces.
  8. 抽象類別可以擴展其他類別並實現介面,但介面只能擴展其他介面。
  9. 如果一個抽象類別有main()方法,我們可以運行它,但無法運行介面,因為介面不能有main方法的實現。
  10. 介面用於定義子類的契約,而抽象類別也定義契約,但它可以為子類提供其他方法的實現。

這就是介面和抽象類別之間的區別,現在我們可以繼續了解何時應該使用介面,何時應該使用抽象類別。

介面或抽象類別

選擇介面或抽象類別來為子類別提供合約是一個設計決策,取決於許多因素。讓我們看看什麼時候介面是最好的選擇,以及何時可以使用抽象類別。

  1. Java不支援多個類級繼承,所以每個類只能擴展一個超類。但是一個類可以實現多個介面。所以大多數情況下,介面是提供類層次結構和合約的好選擇。此外,按照介面編碼是Java編碼的最佳實踐之一。
  2. 如果合約中有很多方法,那麼抽象類別更有用,因為我們可以為一些對於所有子類都相同的方法提供默認實現。而且,如果子類不需要實現特定方法,它們可以避免提供實現,但在介面的情況下,子類將不得不為所有方法提供實現,即使它沒有用處,實現只是一個空塊。
  3. 如果我們的基本合約不斷變化,那麼介面可能會引起問題,因為我們無法在不改變所有實現類的情況下聲明額外的方法。而對於抽象類別,我們可以提供默認實現,只需更改實際使用新方法的實現類。

使用抽象类和接口

同时使用接口和抽象类是设计系统的最佳方法。例如,在JDK中,java.util.List是一个包含许多方法的接口,因此有一个抽象类java.util.AbstractList为List接口的所有方法提供了骨架实现,以便任何子类都可以扩展此类并仅实现所需的方法。我们应该始终从一个接口作为基础开始,定义每个子类都应实现的方法,然后如果有一些方法只有某些子类应该实现,我们可以扩展基础接口并创建一个新的接口带有这些方法。子类将有选择在基础接口或子接口之间选择实现,以符合其需求。如果方法数量增多,为实现子接口提供一个骨架抽象类并为子类提供在接口和抽象类之间选择的灵活性,这并不是一个坏主意。

Java 8接口变更

從 Java 8 開始,我們可以在介面中有方法的實現。我們可以在介面中創建默認方法和靜態方法,並為它們提供實現。這彌合了抽象類和介面之間的差距,現在介面是前進的方式,因為我們可以為新方法提供默認實現來進一步擴展它。更多細節,請查看Java 8 介面默認靜態方法

Source:
https://www.digitalocean.com/community/tutorials/difference-between-abstract-class-and-interface-in-java