談談Java抽象類與接口的區別?java
不少常見的面試題都會出諸如抽象類和接口有什麼區別,什麼狀況下會使用抽象類和什麼狀況你會使用接口這樣的問題。本文咱們將仔細討論這些話題。 抽象類與接口是java語言中對抽象概念進行定義的兩種機制,正是因爲他們的存在才賦予java強大的面向對象的能力。 在討論它們之間的不一樣點以前,咱們先看看抽象類、接口各自的特性。面試
抽象類ide
咱們都知道在面向對象的領域一切都是對象,同時全部的對象都是經過類來描述的,可是並非全部的類都是來描述對象的。若是一個類沒有足夠的信息來描述一個具體的對象,而須要其餘具體的類來支撐它,那麼這樣的類咱們稱它爲抽象類。好比new Animal(),咱們都知道這個是產生一個動物Animal對象,可是這個Animal具體長成什麼樣子咱們並不知道,它沒有一個具體動物的概念,因此他就是一個抽象類,須要一個具體的動物,如狗、貓來對它進行特定的描述,咱們才知道它長成啥樣。設計
在面向對象領域因爲抽象的概念在問題領域沒有對應的具體概念,因此用以表徵抽象概念的抽象類是不能實例化的。對象
抽象類是用來捕捉子類的通用特性的 。它不能被實例化,只能被用做子類的超類。抽象類是被用來建立繼承層級裏子類的模板。以JDK中的GenericServlet爲例:繼承
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {接口
// abstract method編譯器
abstract void service(ServletRequest req, ServletResponse res);it
void init() {io
// Its implementation
}
// other method related to Servlet
}
當HttpServlet類繼承GenericServlet時,它提供了service方法的實現:
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接口爲例:
public interface Externalizable extends Serializable {
void writeExternal(ObjectOutput out) throws IOException;
void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}
當你實現這個接口時,你就須要實現上面的兩個方法:
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方法,所以咱們不能運行它。多繼承抽象方法能夠繼承一個類和實現多個接口接口只能夠繼承一個或多個其它接口速度它比接口速度要快接口是稍微有點慢的,由於它須要時間去尋找在類中實現的方法。添加新方法若是你往抽象類中添加新的方法,你能夠給它提供默認的實現。所以你不須要改變你如今的代碼。若是你往接口中添加方法,那麼你必須改變實現該接口的類。
總結
抽象類和接口是java語言中兩種不一樣的抽象概念,他們的存在對多態提供了很是好的支持,雖然他們之間存在很大的類似性。可是對於他們的選擇每每反應了您對問題域的理解。只有對問題域的本質有良好的理解,才能作出正確、合理的設計。