1. 程式人生 > >3、java基礎:抽象類與接口的區別

3、java基礎:抽象類與接口的區別

style 捕捉 現在 oge () 使用 java 事情 ride

抽象類

我們都知道在面向對象的領域一切都是對象,同時所有的對象都是通過類來描述的,但是並不是所有的類都是來描述對象的。如果一個類沒有足夠的信息來描述一個具體的對象,而需要其他具體的類來支撐它,那麽這樣的類我們稱它為抽象類。比如new Animal(),我們都知道這個是產生一個動物Animal對象,但是這個Animal具體長成什麽樣子我們並不知道,它沒有一個具體動物的概念,所以他就是一個抽象類,需要一個具體的動物,如狗、貓來對它進行特定的描述,我們才知道它長成啥樣。

在面向對象領域由於抽象的概念在問題領域沒有對應的具體概念,所以用以表征抽象概念的抽象類是不能實例化的。

抽象類是用來捕捉子類的通用特性的 。它不能被實例化,只能被用作子類的超類。抽象類是被用來創建繼承層級裏子類的模板。以JDK中的GenericServlet為例:

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方法的實現:

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 }

創建抽象類和抽象方法非常有用,因為他們可以使類的抽象性明確起來,並告訴用戶和編譯器打算怎樣使用他們.抽象類還是有用的重構器,因為它們使我們可以很容易地將公共方法沿著繼承層次結構向上移動。

在使用抽象類時需要註意幾點:

  • 1、抽象類不能被實例化,實例化的工作應該交由它的子類來完成,它只需要有一個引用即可。
  • 2、抽象方法必須由子類來進行重寫。
  • 3、只要包含一個抽象方法的抽象類,該方法必須要定義成抽象類,不管是否還包含有其他方法。
  • 4、抽象類中可以包含具體的方法,當然也可以不包含抽象方法。
  • 5、子類中的抽象方法不能與父類的抽象方法同名。
  • 6、abstract不能與final並列修飾同一個類。
  • 7、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);
    }
}

在使用接口過程中需要註意如下幾個問題:

  • 1、個Interface的方所有法訪問權限自動被聲明為public。確切的說只能為public,當然你可以顯示的聲明為protected、private,但是編譯會出錯!
  • 2、接口中可以定義“成員變量”,或者說是不可變的常量,因為接口中的“成員變量”會自動變為為public static final。可以通過類命名直接訪問:ImplementClass.name。
  • 3、接口中不存在實現的方法。
  • 4、實現接口的非抽象類必須要實現該接口的所有方法。抽象類可以不用實現。
  • 5、不能使用new操作符實例化一個接口,但可以聲明一個接口變量,該變量必須引用(refer to)一個實現該接口的類的對象。可以使用 instanceof 檢查一個對象是否實現了某個特定的接口。例如:if(anObject instanceof Comparable){}。
  • 6、在實現多接口的時候一定要避免方法名的重復。

二者區別

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

總結

  • 1、 抽象類在java語言中所表示的是一種繼承關系,一個子類只能存在一個父類,但是可以存在多個接口。
  • 2、 在抽象類中可以擁有自己的成員變量和非抽象類方法,但是接口中只能存在靜態的不可變的成員數據(不過一般都不在接口中定義成員數據),而且它的所有方法都是抽象的。
  • 3、抽象類和接口所反映的設計理念是不同的,抽象類所代表的是“is-a”的關系,而接口所代表的是“like-a”的關系。

3、java基礎:抽象類與接口的區別