Java基礎:Java抽象類與接口的區別

談談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

}

建立抽象類和抽象方法很是有用,由於他們可使類的抽象性明確起來,並告訴用戶和編譯器打算怎樣使用他們.抽象類仍是有用的重構器,由於它們使咱們能夠很容易地將公共方法沿着繼承層次結構向上移動。

在使用抽象類時須要注意幾點:

  • 一、抽象類不能被實例化,實例化的工做應該交由它的子類來完成,它只須要有一個引用便可。
  • 二、抽象方法必須由子類來進行重寫。
  • 三、只要包含一個抽象方法的抽象類,該方法必需要定義成抽象類,不論是否還包含有其餘方法。
  • 四、抽象類中能夠包含具體的方法,固然也能夠不包含抽象方法。
  • 五、子類中的抽象方法不能與父類的抽象方法同名。
  • 六、abstract不能與final並列修飾同一個類。
  • 七、abstract 不能與private、static、final或native並列修飾同一個方法。

接口

接口是抽象方法的集合。若是一個類實現了某個接口,那麼它就繼承了這個接口的抽象方法。這就像契約模式,若是實現了這個接口,那麼就必須確保使用這些方法。接口只是一種形式,接口自身不能作任何事情。以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);
}
}

在使用接口過程當中須要注意以下幾個問題:

  • 一、個Interface的方全部法訪問權限自動被聲明爲public。確切的說只能爲public,固然你能夠顯示的聲明爲protected、private,可是編譯會出錯!
  • 二、接口中能夠定義「成員變量」,或者說是不可變的常量,由於接口中的「成員變量」會自動變爲爲public static final。能夠經過類命名直接訪問:ImplementClass.name。
  • 三、接口中不存在實現的方法。
  • 四、實現接口的非抽象類必需要實現該接口的全部方法。抽象類能夠不用實現。
  • 五、不能使用new操做符實例化一個接口,但能夠聲明一個接口變量,該變量必須引用(refer to)一個實現該接口的類的對象。可使用 instanceof 檢查一個對象是否實現了某個特定的接口。例如:if(anObject instanceof Comparable){}。
  • 六、在實現多接口的時候必定要避免方法名的重複。

兩者區別

參數抽象類接口默認的方法實現它能夠有默認的方法實現接口徹底是抽象的。它根本不存在方法的實現實現子類使用extends關鍵字來繼承抽象類。若是子類不是抽象類的話,它須要提供抽象類中全部聲明的方法的實現。子類使用關鍵字implements來實現接口。它須要提供接口中全部聲明的方法的實現構造器抽象類能夠有構造器接口不能有構造器與正常Java類的區別除了你不能實例化抽象類以外,它和普通Java類沒有任何區別接口是徹底不一樣的類型訪問修飾符抽象方法能夠有public、protected和default這些修飾符接口方法默認修飾符是public。你不可使用其它修飾符。main方法抽象方法能夠有main方法而且咱們能夠運行它接口沒有main方法,所以咱們不能運行它。多繼承抽象方法能夠繼承一個類和實現多個接口接口只能夠繼承一個或多個其它接口速度它比接口速度要快接口是稍微有點慢的,由於它須要時間去尋找在類中實現的方法。添加新方法若是你往抽象類中添加新的方法,你能夠給它提供默認的實現。所以你不須要改變你如今的代碼。若是你往接口中添加方法,那麼你必須改變實現該接口的類。

總結

  • 一、 抽象類在java語言中所表示的是一種繼承關係,一個子類只能存在一個父類,可是能夠存在多個接口。
  • 二、 在抽象類中能夠擁有本身的成員變量和非抽象類方法,可是接口中只能存在靜態的不可變的成員數據(不過通常都不在接口中定義成員數據),並且它的全部方法都是抽象的。
  • 三、抽象類和接口所反映的設計理念是不一樣的,抽象類所表明的是「is-a」的關係,而接口所表明的是「like-a」的關係。

抽象類和接口是java語言中兩種不一樣的抽象概念,他們的存在對多態提供了很是好的支持,雖然他們之間存在很大的類似性。可是對於他們的選擇每每反應了您對問題域的理解。只有對問題域的本質有良好的理解,才能作出正確、合理的設計。

相關文章
相關標籤/搜索