現在的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的時候給一個抽象類那豈不是把你的實現也告訴別人了嗎。
四、總結
本文主要是由介面和抽象類這個基礎點,帶來的一些思考,越是常見的知識越容易被忽略。又不正之處歡迎指正。