1. 程式人生 > >設計模式(04):介面和抽象類

設計模式(04):介面和抽象類

# 介面和抽象類 ## 區別 介面是對行為的抽象,其重點關注的是要有該行為。

抽象類是對一些共性行為的聚合,將多個子類都有的具體行為抽象成一個方法,形成複用。
```java public abstract class Bird { private String name; private BigDecimal weight; private String habit; } public interface IFlyable { /** * a bird that can fly */ void fly(); } public class Sparrow extends Bird implements IFlyable { @Override public void fly() { Console.log("Sparrow can fly"); } } ``` 舉例來說,這裡我們首先定義了一個 Bird 類,但是,我們卻無法在其中定義 fly 方法,為什麼呢?

因為並不是所有鳥都會飛的,如果是在 Bird 中定義的話,那麼所有實現子類,都擁有這個行為,因此,我們考慮定義介面,來將其行為抽象成一種能力,只要有該能力的類都可以實現該類,這這裡,你甚至可以定義飛機來實現 IFlyable。

而從語法特性來描述的話,有如下區別: - 介面不能有屬性,而抽象類可以有屬性和方法; - 介面中方法不能被實現(Java8 後可以有預設實現方法),抽象類中的方法可以有實現,也可以沒有; ## 使用時機 從上面的例子中,也可以看出何時使用抽象類,何時使用介面,關鍵點是行為的是否可繼承性。

此外,在 Java 要實現多繼承的時候,也只能使用介面,因為 Java 不支援多繼承。
## 存在意義 首先說抽象類。抽象類本質也是一個類,因此類的繼承特性最首要的就是解決程式碼複用的問題。

通過繼承,可以直接複用父類中的方法,並把需要子類來自定義實現的方法定義成 **抽象方法**,從而實現複用。

並且因為繼承的關係,還可以使用面向物件中的 **多型 **特性,用抽象類的指標指向子類的物件。

如果說抽象類關注的是程式碼複用的話,介面更加關注的就是 **解耦。**通過介面定義來讓第三方不要關注具體的實現,如果你要呼叫或是實現自己的方法的話,關注定義即可。

## 深入瞭解 通過,對介面和抽象類的瞭解,現在,我們來看一下,如何在不支援上述語法特性的語言中,實現介面和抽象類呢。
> 在這裡,因為沒有裝 py 和 C++ 的環境,因此就用 Java 簡單代替一下,所完成的邏輯和方法是 的。
**用抽象類來實現介面的定義:** ```java /** * @author iceWang * @date 2020/10/17 * 用抽象類來模擬介面 */ public abstract class AbstractToInterface { protected AbstractToInterface(){}; /** * 類似於介面中的定義,子類必須要實現 */ public abstract void demo(); } ```
用普通類來實現抽象類的作用: ```java /** * @author iceWang * @date 2020/10/17 * 用普通類來模擬抽象類 */ public class ClassToAbstractClass { protected ClassToAbstractClass() { } /** * 類似於抽象類中的抽象方法的定義,因為要保證子類必須重寫,因此直接丟擲異常 */ public void abstractFunction() throws Exception { throw new Exception("Error DesignModel"); } /** * 類似於抽象類中的普通方法的定義,子類不必一定重寫 */ public void plainFunction() { System.out.println("Hello DesignModel"); } } ```
**用普通類來實現介面的定義:** ```java /** * @author iceWang * @date 2020/10/17 * 用普通類來模擬介面 */ public class ClassToInterface { protected ClassToInterface() { } /** * 類似於介面中的定義,因為要保證子類必須實現,因此直接丟擲異常 */ public void demo() throws Exception { throw new Exception("111"); } } ``` ## 介面的使用 介面的實現,可以讓我們在程式設計時採用 **面向介面程式設計** 的思想,即只關注介面定義即可,不必過多關注具體的實現細節,從而實現兩方的解耦。

而為了支援面向介面程式設計,需要在開發過程中: - 函式的命名不能暴露任何實現細節; - 具體的實現細節進行封裝,不暴露給呼叫者; ## 公眾號截圖 ![](https://cdn.nlark.com/yuque/0/2020/jpeg/1166128/1600071237550-30359f9a-9582-44e2-a0e6-49ee404ed5af.jpeg)

文章在公眾號「iceWang」第一手更新,有興趣的朋友可以關注公眾號,第一時間看到筆者分享的各項知識點,謝謝!