學習設計模式時,看到一些術語,瞭解一下 is-a,has-a,like-a含義 假設你確定兩件對象之間是is-a的關係,代表繼承。比如菱形、圓形和方形都是形狀的一種。那麼他們都應該從形狀類繼承。 假設你確定兩件對象之間是has-a的關係,代表聚合,為從屬關係。比如電腦是由顯示器、CPU、硬碟等組成的 ...
學習設計模式時,看到一些術語,瞭解一下
is-a,has-a,like-a含義
假設你確定兩件對象之間是is-a的關係,代表繼承。比如菱形、圓形和方形都是形狀的一種。那麼他們都應該從形狀類繼承。
假設你確定兩件對象之間是has-a的關係,代表聚合,為從屬關係。比如電腦是由顯示器、CPU、硬碟等組成的。那麼你應該把顯示器、CPU、硬碟這些類聚合成電腦類。
假設你確定兩件對象之間是like-a的關係,代表組合關係,實現介面。比如空調繼承於製冷機,但它同一時候有加熱功能。那麼你應該把讓空調繼承製冷機類,並實現加熱介面。
抽象類和介面的對比
參數 | 抽象類 | 介面 |
預設的方法實現 | 它可以有預設的方法實現 | 介面完全是抽象的。它根本不存在方法的實現 |
實現 | 子類使用extends關鍵字來繼承抽象類。如果子類不是抽象類的話,它需要提供抽象類中所有聲明的方法的實現。 | 子類使用關鍵字implements來實現介面。它需要提供介面中所有聲明的方法的實現 |
構造器 | 抽象類可以有構造器 | 介面不能有構造器 |
與正常Java類的區別 | 除了你不能實例化抽象類之外,它和普通Java類沒有任何區別 | 介面是完全不同的類型 |
訪問修飾符 | 抽象方法可以有public、protected和default這些修飾符 | 介面方法預設修飾符是public。你不可以使用其它修飾符。 |
main方法 | 抽象方法可以有main方法並且我們可以運行它 | 介面沒有main方法,因此我們不能運行它。 |
多繼承 | 抽象方法可以繼承一個類和實現多個介面 | 介面只可以繼承一個或多個其它介面 |
速度 | 它比介面速度要快 | 介面是稍微有點慢的,因為它需要時間去尋找在類中實現的方法。 |
添加新方法 | 如果你往抽象類中添加新的方法,你可以給它提供預設的實現。因此你不需要改變你現在的代碼。 |
如果你往介面中添加方法,那麼你必須改變實現該介面的類。 |
什麼時候使用抽象類和介面
- 如果你擁有一些方法並且想讓它們中的一些有預設實現,那麼使用抽象類吧。
- 如果你想實現多重繼承,那麼你必須使用介面。由於Java不支持多繼承,子類不能夠繼承多個類,但可以實現多個介面。因此你就可以使用介面來解決它。
- 如果基本功能在不斷改變,那麼就需要使用抽象類。如果不斷改變基本功能並且使用介面,那麼就需要改變所有實現了該介面的類。
Java8中的預設方法和靜態方法
Oracle已經開始嘗試向介面中引入預設方法和靜態方法,以此來減少抽象類和介面之間的差異。現在,我們可以為介面提供預設實現的方法了並且不用強制子類來實現它。