不少常見的面試題都會出諸如抽象類和接口有什麼區別,什麼狀況下會使用抽象類和什麼狀況你會使用接口這樣的問題。本文咱們將仔細討論這些話題。
在討論它們之間的不一樣點以前,咱們先看看抽象類、接口各自的特性。
抽象類
抽象類是用來捕捉子類的通用特性的 。它不能被實例化,只能被用做子類的超類。抽象類是被用來建立繼承層級裏子類的模板。以JDK中的GenericServlet爲例:
1
2
3
4
5
6
7
8
9
|
public
abstract
class
GenericServlet
implements
Servlet, ServletConfig, Serializable {
// abstract method
abstract
void
service(ServletRequest req, ServletResponse res);
void
init() {
// Its implementation
}
// other method related to Servlet
}
|
當HttpServlet類繼承GenericServlet時,它提供了service方法的實現:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public
class
HttpServlet
extends
GenericServlet {
void
service(ServletRequest req, ServletResponse res) {
// implementation
}
protected
void
doGet(HttpServletRequest req, HttpServletResponse resp) {
// Implementation
}
protected
void
doPost(HttpServletRequest req, HttpServletResponse resp) {
// Implementation
}
// some other methods related to HttpServlet
}
|
接口
接口是抽象方法的集合。若是一個類實現了某個接口,那麼它就繼承了這個接口的抽象方法。這就像契約模式,若是實現了這個接口,那麼就必須確保使用這些方法。接口只是一種形式,接口自身不能作任何事情。以Externalizable接口爲例:
1
2
3
4
5
6
|
public
interface
Externalizable
extends
Serializable {
void
writeExternal(ObjectOutput out)
throws
IOException;
void
readExternal(ObjectInput in)
throws
IOException, ClassNotFoundException;
}
|
當你實現這個接口時,你就須要實現上面的兩個方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
class
Employee
implements
Externalizable {
int
employeeId;
String employeeName;
@Override
public
void
readExternal(ObjectInput in)
throws
IOException, ClassNotFoundException {
employeeId = in.readInt();
employeeName = (String) in.readObject();
}
@Override
public
void
writeExternal(ObjectOutput out)
throws
IOException {
out.writeInt(employeeId);
out.writeObject(employeeName);
}
}
|
抽象類和接口的對比
參數 | 抽象類 | 接口 |
默認的方法實現 | 它能夠有默認的方法實現 | 接口徹底是抽象的。它根本不存在方法的實現 |
實現 | 子類使用extends關鍵字來繼承抽象類。若是子類不是抽象類的話,它須要提供抽象類中全部聲明的方法的實現。 | 子類使用關鍵字implements來實現接口。它須要提供接口中全部聲明的方法的實現 |
構造器 | 抽象類能夠有構造器 | 接口不能有構造器 |
與正常Java類的區別 | 除了你不能實例化抽象類以外,它和普通Java類沒有任何區別 | 接口是徹底不一樣的類型 |
訪問修飾符 | 抽象方法能夠有public、protected和default這些修飾符 | 接口方法默認修飾符是public。你不可使用其它修飾符。 |
main方法 | 抽象方法能夠有main方法而且咱們能夠運行它 | 接口沒有main方法,所以咱們不能運行它。 |
多繼承 | 抽象方法能夠繼承一個類和實現多個接口 | 接口只能夠繼承一個或多個其它接口 |
速度 | 它比接口速度要快 | 接口是稍微有點慢的,由於它須要時間去尋找在類中實現的方法。 |
添加新方法 | 若是你往抽象類中添加新的方法,你能夠給它提供默認的實現。所以你不須要改變你如今的代碼。 | 若是你往接口中添加方法,那麼你必須改變實現該接口的類。 |