欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 抽象類與接口的對比

 更新時間:2020年08月21日 08:44:41   作者:弗蘭克的貓  
這篇文章主要介紹了Java 抽象類與接口的對比,幫助大家更好的理解和學習Java,感興趣的朋友可以了解下

  其實說實話,沒有多大的可比較性,它們是完全不同的兩個東西,它們的抽象不在同一個層級上。但是為了讓大家更好的理解,還是做一個比較吧,畢竟它們都很抽象(233)。

首先是語法層面上的對比

  1)抽象類跟接口都不能被實例化,因為它們都很虛嘛。但是在訪問權限上,兩者有一定的區(qū)別。

  a、抽象類中的抽象方法(其前有abstract修飾)不能用private、static、synchronized、native訪問修飾符修飾。理由很簡單,容我慢慢道來。

  抽象方法是沒有方法體的,它的目的就是用來繼承的,所以如果使用private修飾,不就不能被繼承了嗎?這就違背了它的設計初衷了,所以不能用private來修飾抽象方法。至于static,用它來修飾的方法可以不實例化就可以直接調用,但是抽象方法沒有方法體,使用static修飾就沒有意義了。synchronized是用來加鎖的,如果修飾類中的方法的話,就相當于用this變量鎖,但是抽象類是不能被實例化的,抽象方法也不是在本類中實現(xiàn)而是在子類中實現(xiàn)的,所以鎖應該是子類所屬,所以抽象方法不能用synchronized關鍵字修飾;至于native,這個跟abstract關鍵字本身就是沖突的,abstract聲明方法交給子類實現(xiàn),而native則是交給本地操作系統(tǒng)實現(xiàn),如果同時出現(xiàn),那就相當于把實現(xiàn)交給子類,又交給本地操作系統(tǒng),那最后到底由誰來實現(xiàn)呢?

  綜上所述,抽象類中的抽象方法只能用public和protected修飾。

  b.接口中的方法全部為public abstract修飾,不能使用其他修飾符,而且默認情況(不加任何修飾符)下,也是public abstract的,因為接口只能被類實現(xiàn),不能被類繼承,所以不能使用protected修飾,但接口是可以繼承接口的。

  2)抽象類跟普通類的唯一區(qū)別就是不能被實例化,可以有抽象方法,所以它可以有構造函數(shù),靜態(tài)方法,靜態(tài)代碼塊,可以有普通的成員變量和方法。但是接口就不一樣了,接口只能聲明public abstract的方法和public static final的成員變量。

  3)抽象類本質上還是一個類,只能單繼承,一個類只能繼承一個抽象類,但可以實現(xiàn)多個接口。

其次是概念上的比較

  1)抽象類跟接口的抽象角度不一樣,抽象類一般是對某些具有相似屬性和方法的類進行抽象,抽象出一個統(tǒng)一的父類。而接口則更多的是多一組特定行為的抽象,關注的是行為,而具有這些行為的類之間可能并沒有太大的關聯(lián)性。

  比如說,飛機能上天,鳥能上天,你要是厲害一點,應該也能上天(逃),但顯然兩者之間的關聯(lián)度不大,如果硬是要給它們插上一個公共的父類的話,似乎不合情理,看起來就像這樣:

public abstract class Flyer {
  public abstract void fly();
}

  然后定義兩個類來繼承它:

public class Airplane extends Flyer {

  @Override
  public void fly() {
    System.out.println("Airplane is flying.");
  }
}
public class Bird extends Flyer {

  @Override
  public void fly() {
    System.out.println("Bird is flying.");
  }
}

  好的,現(xiàn)在寫一個測試類:

public class Test {
  public static void main(String[] args) {
    Flyer[] flyer = new Flyer[2];
    flyer[0] = new Airplane();
    flyer[1] = new Bird();
    for (Flyer f:flyer){
      f.fly();
    }
  }
}

  運行結果如下:

Airplane is flying.
Bird is flying.

  乍眼一看,好像運行良好,但是仔細想想,將兩個關聯(lián)度很低的類強行插上一個父類,似乎有些不妥,畢竟飛機跟鳥除了都能飛以外,基本沒有什么相似的地方了,而且兩者的飛行方式,飛行速度和高度都相去甚遠,也就是說除了這個fly的方法,其他方法都要在各自的子類實現(xiàn),而且一個類只能繼承一個抽象類,所以Bird類和Airplane類就無法再繼承其他類了,這樣就反而限制了程序的靈活性。所以,這種時候,還是比較適合使用接口:

public interface IFlyable {
  //聲明Fly方法
  void fly();
}

  而此時只需要將Airplane類和Bird類的extends Flyer改成implement Flyable即可。

public class Airplane implements IFlyable {

  //實現(xiàn)Fly方法
  @Override
  public void fly() {
    System.out.println("Airplane is flying.");
  }
}
public class Bird implements IFlyable {
  //實現(xiàn)Fly方法
  @Override
  public void fly() {
    System.out.println("Bird is flying.");
  }
}

  再修改一下Test類:

public class Test {
  public static void main(String[] args) {
    IFlyable[] flyer = new IFlyable[2];
    flyer[0] = new Airplane();
    flyer[1] = new Bird();
    for (IFlyable f:flyer){
      f.fly();
    }
  }
}

  輸出如下:

Airplane is flying.
Bird is flying.

  也許從這個栗子還沒法明顯的看出兩者的區(qū)別,那么我們再換一個栗子,人可以坐飛機,可以坐火車,還可以坐汽車,只要它們有載人功能即可,那用接口實現(xiàn)如下:

public interface ICarryPassenger {

  //聲明載客方法
  void carry(Passenger passenger);
}

  定義一個乘客類,用姓名來區(qū)分各個乘客。

public class Passenger {

  private String name;//乘客姓名

  public Passenger(String name){
    this.name = name;
  }

  public String getName() {
    return name;
  }

  //出行方式
  public void travelBy(ICarryPassenger ic){
    ic.carry(this);
  }
}

  分別定義汽車類,火車類,飛機類,它們都實現(xiàn)ICarryPassenger接口,飛機還可以實現(xiàn)IFlyable接口(雖然沒有用到。。):

public class Car implements ICarryPassenger {

  int passengerNum;

  //實現(xiàn)carry方法
  @Override
  public void carry(Passenger passenger) {
    System.out.println("Passenger:"+passenger.getName()+" travel by Car.");
    passengerNum++;
    System.out.println("Car carries: "+passengerNum+" passenger.");
  }
}
public class Train implements ICarryPassenger {

  int passengerNum;

  @Override
  public void carry(Passenger passenger) {
    System.out.println("Passenger:"+passenger.getName()+" travel by Train.");
    passengerNum++;
    System.out.println("Train carries: "+passengerNum+" passenger.");
  }
}
public class Airplane implements IFlyable,ICarryPassenger{

  private int passengerNum;//乘客數(shù)量

  //實現(xiàn)Fly方法
  @Override
  public void fly() {
    System.out.println("Airplane is flying.");
  }

  //實現(xiàn)carry方法
  @Override
  public void carry(Passenger passenger) {
    System.out.println("Passenger:"+passenger.getName()+" travel by Airplane.");
    passengerNum++;
    System.out.println("Airplane carries: "+passengerNum+" passengers.");
  }
}

  好的,現(xiàn)在我們寫一個測試類來進行測試:

public class Test {
  public static void main(String[] args) {
    //有6個乘客想要去旅游,對于旅行方式沒有側重,隨機分配交通工具
    Random random = new Random();
    Passenger[] passengers = new Passenger[6];//聲明6個乘客
    for (int i=0;i<6;i++){
      passengers[i] = new Passenger("Passenger["+i+"]");
    }
    ICarryPassenger[] icp = new ICarryPassenger[3];//聲明3種交通方式
    icp[0] = new Airplane();
    icp[1] = new Car();
    icp[2] = new Train();
    for (int i=0;i<6;i++){
      passengers[i].travelBy(icp[random.nextInt(3)]);
    }
  }
}

  輸出如下:

Passenger:Passenger[0] travel by Airplane.
Airplane carries: 1 passengers.
Passenger:Passenger[1] travel by Train.
Train carries: 1 passenger.
Passenger:Passenger[2] travel by Airplane.
Airplane carries: 2 passengers.
Passenger:Passenger[3] travel by Car.
Car carries: 1 passenger.
Passenger:Passenger[4] travel by Train.
Train carries: 2 passenger.
Passenger:Passenger[5] travel by Airplane.
Airplane carries: 3 passengers.

  因為飛機跟火車,汽車之間并沒有太大關聯(lián),顯然無法直接抽象出父類,它們僅有相同的行為,那就是載客,所以使用接口是最合適的。

  至此,本篇講解完畢,想必通過這一篇的講解,對于抽象類和接口的區(qū)別應該有了更好的理解吧,如果有更好的栗子,歡迎大家留言交流,也歡迎大家繼續(xù)關注。

以上就是Java 抽象類與接口的對比的詳細內容,更多關于Java 抽象類與接口的資料請關注腳本之家其它相關文章!

相關文章

  • screw?Maven插件方式運行時在編譯打包時跳過執(zhí)行的問題解決方法

    screw?Maven插件方式運行時在編譯打包時跳過執(zhí)行的問題解決方法

    這篇文章主要介紹了screw?Maven插件方式運行時在編譯打包時跳過執(zhí)行的問題解決方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • Java?AQS中ReentrantLock條件鎖的使用

    Java?AQS中ReentrantLock條件鎖的使用

    ReentrantLock繼承了Lock接口,?lock方法實際上是調用了Sync的子類NonfairSync(非公平鎖)的lock方法。ReentrantLock的真正實現(xiàn)在他的兩個內部類NonfairSync和FairSync中,默認實現(xiàn)是非公平鎖
    2023-02-02
  • 詳解SpringBoot統(tǒng)一響應體解決方案

    詳解SpringBoot統(tǒng)一響應體解決方案

    這篇文章主要介紹了詳解SpringBoot統(tǒng)一響應體解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-07-07
  • Intellij IDEA安裝lombok插件及使用詳解

    Intellij IDEA安裝lombok插件及使用詳解

    今天小編就為大家分享一篇關于Intellij IDEA安裝lombok插件及使用詳解,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Java中四種引用類型詳細介紹

    Java中四種引用類型詳細介紹

    這篇文章主要介紹了Java中四種引用類型詳細介紹的相關資料,需要的朋友可以參考下
    2017-03-03
  • 實例分析Java泛型

    實例分析Java泛型

    本篇文章通過代碼實例給大家講述了Java泛型的相關知識點以及相關的代碼分析,對此有興趣的朋友學習下。
    2018-02-02
  • WIN7系統(tǒng)JavaEE(tomcat7 Eclipse)環(huán)境配置教程(二)

    WIN7系統(tǒng)JavaEE(tomcat7 Eclipse)環(huán)境配置教程(二)

    這篇文章主要介紹了WIN7系統(tǒng)JavaEE(java+tomcat7+Eclipse)環(huán)境配置教程,本文重點在于tomcat配置、Eclipse配置,感興趣的小伙伴們可以參考一下
    2016-06-06
  • java 三元操作符用法說明

    java 三元操作符用法說明

    這篇文章主要介紹了java 三元操作符用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • 解決MyBatisPlus的updateBatchById()批量修改失效問題

    解決MyBatisPlus的updateBatchById()批量修改失效問題

    這篇文章主要介紹了解決MyBatisPlus的updateBatchById()批量修改失效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java的分片上傳功能的實現(xiàn)

    Java的分片上傳功能的實現(xiàn)

    本文主要介紹了Java的分片上傳功能的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02

最新評論