1. 程式人生 > >Java——抽象類和介面的區別

Java——抽象類和介面的區別

一.  區別

1.語法層面上的區別

  1)抽象類可以提供成員方法的實現細節,而介面中只能存在public abstract 方法;

  2)抽象類中的成員變數可以是各種型別的,而介面中的成員變數只能是public static final型別的;

  3)介面中不能含有靜態程式碼塊以及靜態方法,而抽象類可以有靜態程式碼塊和靜態方法;

  4)一個類只能繼承一個抽象類,而一個類卻可以實現多個介面。

2.設計層面上的區別

1)抽象類是對一種事物的抽象,即對類抽象,而介面是對行為的抽象。抽象類是對整個類整體進行抽象,包括屬性、行為,但是介面卻是對類區域性(行為)進行抽象。繼承是一個 "是不是"的關係,而 介面 實現則是 "有沒有"的關係。

2)設計層面不同,抽象類作為很多子類的父類,它是一種模板式設計。而介面是一種行為規範,它是一種輻射式設計。

 

二.  抽象類和介面的對比

  抽象類 介面
預設的方法實現 它可以有預設的方法實現 介面完全是抽象的。它根本不存在方法的實現
實現 子類使用extends關鍵字來繼承抽象類。如果子類不是抽象類的話,它需要提供抽象類中所有宣告的方法的實現。 子類使用關鍵字implements來實現介面。它需要提供介面中所有宣告的方法的實現
構造器 抽象類可以有構造器 介面不能有構造器
與正常Java類的區別 除了你不能例項化抽象類之外,它和普通Java類沒有任何區別 介面是完全不同的型別
訪問修飾符 抽象方法可以有publicprotecteddefault這些修飾符 介面方法預設修飾符是public。你不可以使用其它修飾符。
main方法 抽象方法可以有main方法並且我們可以執行它 介面沒有main方法,因此我們不能執行它。
多繼承 抽象方法可以繼承一個類和實現多個介面 介面只可以繼承一個或多個其它介面
速度 它比介面速度要快 介面是稍微有點慢的,因為它需要時間去尋找在類中實現的方法。
新增新方法 如果你往抽象類中新增新的方法,你可以給它提供預設的實現。因此你不需要改變你現在的程式碼。 如果你往介面中新增方法,那麼你必須改變實現該介面的類。

三.  什麼時候使用抽象類和介面

  • 如果你擁有一些方法並且想讓它們中的一些有預設實現,那麼使用抽象類吧。
  • 如果你想實現多重繼承,那麼你必須使用介面。由於Java不支援多繼承,子類不能夠繼承多個類,但可以實現多個介面。因此你就可以使用介面來解決它。
  • 如果基本功能在不斷改變,那麼就需要使用抽象類。如果不斷改變基本功能並且使用介面,那麼就需要改變所有實現了該介面的類。

模板設計例項(用兩種方式列印1000以內質數,並求消耗時間)

package com.zth;

abstract class  Template{
  
  public void time() {
    long start = System.currentTimeMillis();
    
    code();
    
    long end  = System.currentTimeMillis();
    
    System.out.println("\n"+(end-start));
  }
  
  abstract void code();
}

class ZhiShu1 extends Template{
    // 列印100以內的質數
  void code() {
    for(int i = 2;i<=1000;i++) {
      int j = 2;
      while(j<=i) {
        if(i%j ==0) {
          break;
        }
        j++;
      }
      if(i == j) {
        System.out.print(i+ "  ");
      }
    }
    
  }
}

class ZhiShu2 extends Template{
  // 列印100以內的質數
void code() {
  for(int i = 2;i<=1000;i++) {
    int j = 2;
    while(j<=Math.sqrt(i)) {
      if(i %j == 0) {
        break;
      }
      j++;
    }
    if(j > Math.sqrt(i)) {
      System.out.print(i+ "  ");
    }
  }
  
}
}

public class Test{
  public static void main(String[] args) {
    ZhiShu1 a = new ZhiShu1();
    a.time();
    ZhiShu2 b = new ZhiShu2();
    b.time();
  }
}

執行結果:

2  3  5  7  11  13  17  19  23  29  31  37  41  43  47  53  59  61  67  71  73  79  83  89  97  101  103  107  109  113  127  131  137  139  149  151  157  163  167  173  179  181  191  193  197  199  211  223  227  229  233  239  241  251  257  263  269  271  277  281  283  293  307  311  313  317  331  337  347  349  353  359  367  373  379  383  389  397  401  409  419  421  431  433  439  443  449  457  461  463  467  479  487  491  499  503  509  521  523  541  547  557  563  569  571  577  587  593  599  601  607  613  617  619  631  641  643  647  653  659  661  673  677  683  691  701  709  719  727  733  739  743  751  757  761  769  773  787  797  809  811  821  823  827  829  839  853  857  859  863  877  881  883  887  907  911  919  929  937  941  947  953  967  971  977  983  991  997  
8
2  3  5  7  11  13  17  19  23  29  31  37  41  43  47  53  59  61  67  71  73  79  83  89  97  101  103  107  109  113  127  131  137  139  149  151  157  163  167  173  179  181  191  193  197  199  211  223  227  229  233  239  241  251  257  263  269  271  277  281  283  293  307  311  313  317  331  337  347  349  353  359  367  373  379  383  389  397  401  409  419  421  431  433  439  443  449  457  461  463  467  479  487  491  499  503  509  521  523  541  547  557  563  569  571  577  587  593  599  601  607  613  617  619  631  641  643  647  653  659  661  673  677  683  691  701  709  719  727  733  739  743  751  757  761  769  773  787  797  809  811  821  823  827  829  839  853  857  859  863  877  881  883  887  907  911  919  929  937  941  947  953  967  971  977  983  991  997  
4