抽象類和接口,你瞭解多少?

  現在的java開發一般都說面向接口編程,在開發過程中使用的最多的是給service層每個方法寫一個接口,如果用到了DAO層,那麼也是一個Mapper接口,之後的事情就交給mybatis框架去做了。總之編程過程中充斥着接口,有一個和接口很相似的叫做“抽象類”的不知道是否還記得。今天想聊聊接口和抽象類的那些事。

一、什麼是接口,什麼是抽象類

  接口和抽象類就像是一隊孿生兄弟,有時候除了從定義上來區分,其他地方用什麼似乎都是可以的。

  接口,可以理解爲定義一組協議,一類操作流程。經常聽到“你把這個類抽象出一個接口出來”這樣的話,那麼接口是什麼樣子,如在java的API中有AutoCloseable接口,

該接口僅僅定義了一個close()方法,拋出Exception異常,看下該接口上的註釋

意思大概是close()方法不像java.io.Closeable接口中的close()方法需要冪等性,該接口不需要冪等性,同時強烈建議實現類或接口實現自己的close()方法。既然提到了java.io.Closeable那麼我們看下該接口是什麼樣子的,

該接口繼承了java.lang.AutoCloseale接口,且有自己的close()方法,該方法拋出的是IOException,也就是說該接口和IO相關。

從上面我們可以得出一個結論接口是可以繼承接口的

我們比較java.lang.AutoCloseable和java.io.Closeable這兩個接口,都是隻有兩個close()方法,但看java.lang.AutoCloseable接口,你根本看不出什麼東西,它可以說是一個高度的抽象,僅僅是關閉一個資源,而且拋出的是Exception異常,簡直太抽象了,感興趣的可以閱讀下該類上的註釋。那麼到了java.io.Closeable同樣是一個close()方法,不過這裏確實拋出一個IOExcetion異常,那麼就是和IO相關的拉。從上面可以看出接口肯定是高度抽象的。反觀我們平時寫的代碼,動不動就是一個接口,抽象程度肯定不夠,

 

下面看下java.io.Closeable的一個實現類java.io.InputStream,你沒看錯就是平時使用的文件操作類InputStream,它不是一個接口,而是一個抽象類

從上圖可以看到InputStream實現了Closeable接口,且該抽象類中還有其他一些read()、skip()、avaliable()方法等。

先看下實現的close()方法吧,

該方法是一個空方法,沒用任何實現,意味着等待InputStream的子類去覆蓋,例如BufferedInputStream是這樣實現的,

再回過頭來看下InputStream類中的read()方法,

這個方法是抽象的,而另外一個read()方法是有實現的,

從這裏可以看出,抽象類中可以有非抽象方法

 

  舉了這麼多的例子,無非是想大家對接口和抽象類能有一個感官上的認識,現在對其做個總結,

  接口定義了一組協議或標識某個功能,接口可以實現接口,接口中的方法都是public static final的。

  抽象類是一種特殊的類,無法實例化,只能被繼承,只要類中有一個方法是抽象的那麼該類就說抽象的,抽象類中可以有非抽象方法。

  java8開始接口中可以有default修飾的方法。

二、怎麼使用接口,怎麼使用抽象類

前面說了很多關於接口和抽象類的內容,那麼接口和抽象類要怎麼使用,想必定義都是不陌生的,類似,

package com.my.day01;

/**
 * 汽車接口
 * @date 2022/5/22 21:00
 */
public interface CarInterface {
    void run()throws Exception;
}

抽象類,

 

package com.my.day01;

/**
 * 抽象的汽車類
 * @date 2022/5/22 21:02
 */
public abstract class AbstractCar implements CarInterface {
    @Override public void run() throws Exception {
        System.out.println("running.....");
    }
    /**
     * 加油
     * 不同的car加的油不一樣,有汽油、柴油,有92 95等
     */
    public abstract void fillGas();
    /**
     * 掛擋
     */
    public void gear() {
        System.out.println("掛擋");
    }
}

上面就是接口和抽象類的使用,有個很重要的問題,什麼時候該用接口什麼使用該用抽象類,我有這樣的一些想法,供參考。接口必須是高度抽象的,從所有的類中抽象出來公有的方法,那麼這個方法就應該是在接口中;對於一些不是所有的類都有的行爲,我們可以抽取到抽象類中實現爲抽象方法,供不同的子類去實現。我認爲接口和抽象類之間還是有不少區別的。

三、接口、抽象類的區別是什麼

  接口和抽象類中有什麼樣的區別?難到不可以僅用其中一個嗎?這個肯定是不行的。首先,接口定義的是一組規範,一組協議,她不負責任何實現,而在抽象類中是可以有非抽象方法的,也就是說抽象類可以提供一部分實現,僅把部分作爲抽象供子類去覆蓋;其次,現在都講面向接口編程,你給人提供API的時候給一個抽象類那豈不是把你的實現也告訴別人了嗎。

四、總結

  本文主要是由接口和抽象類這個基礎點,帶來的一些思考,越是常見的知識越容易被忽略。又不正之處歡迎指正。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章